Skip to content

Commit 2227380

Browse files
authored
Merge pull request #840 from esben-semmle/js/propagate-sound-avalue
Approved by xiemaisi
2 parents ee45266 + 5d5900a commit 2227380

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

change-notes/1.20/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
* The taint tracking library now recognizes flow through persistent storage, class fields, and callbacks in certain cases. This may give more results for the security queries.
1212

13+
* Type inference for function calls has been improved. This may give additional results for queries that rely on type inference.
14+
1315
## New queries
1416

1517
| **Query** | **Tags** | **Purpose** |

javascript/ql/src/semmle/javascript/dataflow/internal/VariableTypeInference.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,27 @@ private class SsaVarAccessAnalysis extends DataFlow::AnalyzedValueNode {
4141
override AbstractValue getALocalValue() { result = def.getAnRhsValue() }
4242
}
4343

44+
/**
45+
* Flow analysis for accesses to SSA variables.
46+
*
47+
* Unlike `SsaVarAccessAnalysis`, this only contributes to `getAValue()`, not `getALocalValue()`.
48+
*/
49+
private class SsaVarAccessWithNonLocalAnalysis extends SsaVarAccessAnalysis {
50+
DataFlow::AnalyzedValueNode src;
51+
52+
SsaVarAccessWithNonLocalAnalysis() {
53+
exists(VarDef varDef |
54+
varDef = def.(SsaExplicitDefinition).getDef() and
55+
varDef.getSource().flow() = src and
56+
src instanceof CallWithNonLocalAnalyzedReturnFlow and
57+
// avoid relating `v` and `f()` in `var {v} = f();`
58+
not varDef.getTarget() instanceof DestructuringPattern
59+
)
60+
}
61+
62+
override AbstractValue getAValue() { result = src.getAValue() }
63+
}
64+
4465
/**
4566
* Flow analysis for `VarDef`s.
4667
*/

javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
| UselessConditional.js:129:6:129:24 | constantUndefined() | This call to constantUndefined always evaluates to false. |
2626
| UselessConditional.js:135:6:135:32 | constan ... ined1() | This call to constantFalseOrUndefined1 always evaluates to false. |
2727
| UselessConditional.js:139:6:139:32 | constan ... ined2() | This call to constantFalseOrUndefined2 always evaluates to false. |
28+
| UselessConditional.js:148:6:148:8 | p() | This call to p always evaluates to true. |
29+
| UselessConditional.js:151:6:151:6 | v | This use of variable 'v' always evaluates to true. |
30+
| UselessConditional.js:163:5:163:17 | findOrThrow() | This call to findOrThrow always evaluates to true. |
31+
| UselessConditional.js:166:6:166:6 | v | This use of variable 'v' always evaluates to true. |
2832
| UselessConditionalGood.js:58:12:58:13 | x2 | This use of variable 'x2' always evaluates to false. |
2933
| UselessConditionalGood.js:69:12:69:13 | xy | This use of variable 'xy' always evaluates to false. |
3034
| UselessConditionalGood.js:85:12:85:13 | xy | This use of variable 'xy' always evaluates to false. |

javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,41 @@ async function awaitFlow(){
140140
return;
141141

142142
});
143+
144+
(function () {
145+
function p() {
146+
return {};
147+
}
148+
if (p()) { // NOT OK
149+
}
150+
var v = p();
151+
if (v) { // NOT OK
152+
}
153+
if (v) { // NOT OK, but not detected due to SSA limitations
154+
}
155+
});
156+
157+
(function() {
158+
function findOrThrow() {
159+
var e = find();
160+
if (e) return e;
161+
throw new Error();
162+
}
163+
if(findOrThrow()){ // NOT OK
164+
}
165+
var v = findOrThrow();
166+
if (v) { // NOT OK
167+
}
168+
if (v) { // NOT OK, but not detected due to SSA limitations
169+
}
170+
});
171+
172+
(function () {
173+
function f(){ return { v: unkown };}
174+
f();
175+
var { v } = f();
176+
if (v) { // OK
177+
}
178+
});
179+
143180
// semmle-extractor-options: --experimental

0 commit comments

Comments
 (0)