Skip to content

Commit e6bfe2b

Browse files
authored
Merge pull request #1873 from asger-semmle/type-inf-consistency
Approved by xiemaisi
2 parents 1bb57da + 7790d4b commit e6bfe2b

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

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

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,50 @@ private class AnalyzedCapturedVariable extends @variable {
3131
}
3232

3333
/**
34-
* Flow analysis for accesses to SSA variables.
34+
* Flow analysis for SSA nodes.
3535
*/
36-
private class SsaVarAccessAnalysis extends DataFlow::AnalyzedValueNode {
37-
AnalyzedSsaDefinition def;
36+
private class AnalyzedSsaDefinitionNode extends AnalyzedNode, DataFlow::SsaDefinitionNode {
37+
override AbstractValue getALocalValue() { result = ssa.(AnalyzedSsaDefinition).getAnRhsValue() }
38+
}
3839

39-
SsaVarAccessAnalysis() { astNode = def.getVariable().getAUse() }
40+
/**
41+
* An SSA definition whose right-hand side is a call with non-local data flow.
42+
*/
43+
private class SsaDefinitionWithNonLocalFlow extends SsaExplicitDefinition {
44+
CallWithNonLocalAnalyzedReturnFlow source;
45+
46+
SsaDefinitionWithNonLocalFlow() {
47+
source = getDef().getSource().flow()
48+
}
4049

41-
override AbstractValue getALocalValue() { result = def.getAnRhsValue() }
50+
CallWithNonLocalAnalyzedReturnFlow getSource() { result = source }
4251
}
4352

4453
/**
45-
* Flow analysis for accesses to SSA variables.
46-
*
47-
* Unlike `SsaVarAccessAnalysis`, this only contributes to `getAValue()`, not `getALocalValue()`.
54+
* Flow analysis for SSA nodes corresponding to `SsaDefinitionWithNonLocalFlow`.
4855
*/
49-
private class SsaVarAccessWithNonLocalAnalysis extends SsaVarAccessAnalysis {
50-
DataFlow::AnalyzedValueNode src;
56+
private class AnalyzedSsaDefinitionNodeWithNonLocalAnalysis extends AnalyzedSsaDefinitionNode {
57+
override SsaDefinitionWithNonLocalFlow ssa;
5158

52-
SsaVarAccessWithNonLocalAnalysis() {
53-
exists(VarDef varDef |
54-
varDef = def.(SsaExplicitDefinition).getDef() and
55-
varDef.getSource().flow() = src and
56-
src instanceof CallWithNonLocalAnalyzedReturnFlow
57-
)
59+
override AbstractValue getAValue() {
60+
result = ssa.getSource().getAValue()
61+
}
62+
}
63+
64+
/**
65+
* Flow analysis for uses of an SSA variable corresponding to `SsaDefinitionWithNonLocalFlow`.
66+
*/
67+
private class AnalyzedSsaVariableUseWithNonLocalFlow extends AnalyzedValueNode {
68+
SsaDefinitionWithNonLocalFlow ssaDef;
69+
70+
AnalyzedSsaVariableUseWithNonLocalFlow() {
71+
this = DataFlow::valueNode(ssaDef.getVariable().getAUse())
5872
}
5973

60-
override AbstractValue getAValue() { result = src.getAValue() }
74+
override AbstractValue getAValue() {
75+
// Block indefinite values coming from getALocalValue()
76+
result = ssaDef.getSource().getAValue()
77+
}
6178
}
6279

6380
/**
@@ -620,7 +637,11 @@ private class ReflectiveVarFlow extends DataFlow::AnalyzedValueNode {
620637
)
621638
}
622639

623-
override AbstractValue getALocalValue() { result = TIndefiniteAbstractValue("eval") }
640+
override AbstractValue getALocalValue() {
641+
result = TIndefiniteAbstractValue("eval")
642+
or
643+
result = AnalyzedValueNode.super.getALocalValue()
644+
}
624645
}
625646

626647
/**
@@ -632,7 +653,11 @@ private class ReflectiveVarFlow extends DataFlow::AnalyzedValueNode {
632653
private class NamespaceExportVarFlow extends DataFlow::AnalyzedValueNode {
633654
NamespaceExportVarFlow() { astNode.(VarAccess).getVariable().isNamespaceExport() }
634655

635-
override AbstractValue getALocalValue() { result = TIndefiniteAbstractValue("namespace") }
656+
override AbstractValue getALocalValue() {
657+
result = TIndefiniteAbstractValue("namespace")
658+
or
659+
result = AnalyzedValueNode.super.getALocalValue()
660+
}
636661
}
637662

638663
/**

javascript/ql/test/library-tests/CallGraphs/FullTest/tests.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ test_isUncertain
3636
| tst.js:69:1:69:10 | globalfn() |
3737
test_getAFunctionValue
3838
| a.js:1:8:1:10 | foo | b.js:1:16:1:27 | function(){} |
39+
| a.js:1:8:1:10 | foo | b.js:1:16:1:27 | function(){} |
40+
| a.js:1:15:1:17 | bar | b.js:2:8:2:24 | function bar() {} |
3941
| a.js:1:15:1:17 | bar | b.js:2:8:2:24 | function bar() {} |
4042
| a.js:1:20:1:22 | qux | c.js:2:8:2:24 | function bar() {} |
43+
| a.js:1:20:1:22 | qux | c.js:2:8:2:24 | function bar() {} |
4144
| a.js:2:1:2:3 | foo | b.js:1:16:1:27 | function(){} |
4245
| a.js:3:1:3:3 | bar | b.js:2:8:2:24 | function bar() {} |
4346
| a.js:4:1:4:3 | qux | c.js:2:8:2:24 | function bar() {} |

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
typeInferenceMismatch
2-
| addexpr.js:4:10:4:17 | source() | addexpr.js:4:5:4:17 | x |
3-
| addexpr.js:4:10:4:17 | source() | addexpr.js:6:3:6:14 | x |
4-
| addexpr.js:11:15:11:22 | source() | addexpr.js:17:5:17:18 | value |
5-
| addexpr.js:11:15:11:22 | source() | addexpr.js:19:3:19:14 | value |
62
| destruct.js:20:7:20:14 | source() | destruct.js:13:14:13:19 | [a, b] |
73
#select
84
| access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x |

0 commit comments

Comments
 (0)