File tree Expand file tree Collapse file tree 8 files changed +38
-2
lines changed
lib/semmle/javascript/dataflow
query-tests/Statements/UselessConditional Expand file tree Collapse file tree 8 files changed +38
-2
lines changed Original file line number Diff line number Diff line change @@ -1693,7 +1693,11 @@ module DataFlow {
16931693 exists ( Expr predExpr , Expr succExpr |
16941694 pred = valueNode ( predExpr ) and succ = valueNode ( succExpr )
16951695 |
1696- predExpr = succExpr .( LogicalBinaryExpr ) .getAnOperand ( )
1696+ predExpr = succExpr .( LogicalOrExpr ) .getAnOperand ( )
1697+ or
1698+ predExpr = succExpr .( NullishCoalescingExpr ) .getAnOperand ( )
1699+ or
1700+ predExpr = succExpr .( LogicalAndExpr ) .getRightOperand ( )
16971701 or
16981702 predExpr = succExpr .( ConditionalExpr ) .getABranch ( )
16991703 or
Original file line number Diff line number Diff line change @@ -238,6 +238,26 @@ private class AnalyzedBinaryExpr extends DataFlow::AnalyzedValueNode {
238238 }
239239}
240240
241+ pragma [ nomagic]
242+ private predicate falsyValue ( AbstractValue value ) { value .getBooleanValue ( ) = false }
243+
244+ /**
245+ * Flow analysis for `&&` operators.
246+ */
247+ private class AnalyzedLogicalAndExpr extends DataFlow:: AnalyzedValueNode {
248+ override LogicalAndExpr astNode ;
249+
250+ pragma [ nomagic]
251+ private AnalyzedValueNode leftOperand ( ) { result = astNode .getLeftOperand ( ) .analyze ( ) }
252+
253+ override AbstractValue getALocalValue ( ) {
254+ result = super .getALocalValue ( )
255+ or
256+ result = this .leftOperand ( ) .getALocalValue ( ) and
257+ falsyValue ( result )
258+ }
259+ }
260+
241261/**
242262 * Gets the `n`th operand of the given `+` or `+=` expression.
243263 */
Original file line number Diff line number Diff line change 1+ ---
2+ category : fix
3+ ---
4+ * The left operand of the ` && ` operator no longer propagates data flow by default.
Original file line number Diff line number Diff line change @@ -1022,7 +1022,6 @@ flowStep
10221022| tst.js:4:9:4:12 | "hi" | tst.js:4:5:4:12 | y |
10231023| tst.js:9:2:9:2 | x | tst.js:9:1:9:3 | (x) |
10241024| tst.js:10:4:10:4 | y | tst.js:10:1:10:4 | x, y |
1025- | tst.js:11:1:11:1 | x | tst.js:11:1:11:6 | x && y |
10261025| tst.js:11:1:11:1 | x | tst.js:12:1:12:1 | x |
10271026| tst.js:11:1:11:1 | x | tst.js:12:1:12:1 | x |
10281027| tst.js:11:6:11:6 | y | tst.js:11:1:11:6 | x && y |
Original file line number Diff line number Diff line change @@ -154,6 +154,7 @@ typeInferenceMismatch
154154| json-stringify.js:2:16:2:23 | source() | json-stringify.js:42:8:42:51 | JSON.st ... urce))) |
155155| json-stringify.js:2:16:2:23 | source() | json-stringify.js:45:8:45:23 | fastJson(source) |
156156| json-stringify.js:3:15:3:22 | source() | json-stringify.js:8:8:8:31 | jsonStr ... (taint) |
157+ | logical-and.js:2:17:2:24 | source() | logical-and.js:4:10:4:24 | "safe" && taint |
157158| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x |
158159| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y |
159160| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) |
Original file line number Diff line number Diff line change 7373| importedReactComponent.jsx:4:40:4:47 | source() | exportedReactComponent.jsx:2:10:2:19 | props.text |
7474| indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x |
7575| indexOf.js:4:11:4:18 | source() | indexOf.js:13:10:13:10 | x |
76+ | logical-and.js:2:17:2:24 | source() | logical-and.js:4:10:4:24 | "safe" && taint |
7677| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x |
7778| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y |
7879| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) |
Original file line number Diff line number Diff line change 1+ function test ( ) {
2+ var taint = source ( ) ;
3+
4+ sink ( "safe" && taint ) ; // NOT OK
5+ sink ( taint && "safe" ) ; // OK
6+ }
Original file line number Diff line number Diff line change 1818| UselessConditional.js:94:16:94:16 | x | This use of variable 'x' always evaluates to false. |
1919| UselessConditional.js:100:13:100:24 | true && true | This expression always evaluates to true. |
2020| UselessConditional.js:101:18:101:18 | x | This use of variable 'x' always evaluates to false. |
21+ | UselessConditional.js:102:13:102:20 | y && (x) | This expression always evaluates to false. |
2122| UselessConditional.js:102:19:102:19 | x | This use of variable 'x' always evaluates to false. |
2223| UselessConditional.js:103:23:103:23 | x | This use of variable 'x' always evaluates to false. |
2324| UselessConditional.js:109:15:109:16 | {} | This expression always evaluates to true. |
You can’t perform that action at this time.
0 commit comments