Skip to content

Commit 1d994b0

Browse files
committed
JS: Update type inference
1 parent d5d08da commit 1d994b0

File tree

2 files changed

+36
-45
lines changed

2 files changed

+36
-45
lines changed

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -416,23 +416,3 @@ private class AnalyzedOptionalChainExpr extends DataFlow::AnalyzedValueNode {
416416
result = TAbstractUndefined()
417417
}
418418
}
419-
420-
/**
421-
* Flow analysis for parameter AST nodes.
422-
*
423-
* For legacy reasons this node takes its value from the SSA variable node,
424-
* even though the SSA variable node is a successor of this node.
425-
*/
426-
private class AnalyzedParameterValueNode extends AnalyzedNode {
427-
Parameter p;
428-
429-
AnalyzedParameterValueNode() {
430-
DataFlow::parameterNode(this, p)
431-
}
432-
433-
override AbstractValue getAValue() {
434-
result = p.(AnalyzedVarDef).getAnRhsValue()
435-
or
436-
result = TIndefiniteAbstractValue("call")
437-
}
438-
}

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

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class AnalyzedVarDef extends VarDef {
120120
* due to the given `cause`.
121121
*/
122122
predicate isIncomplete(DataFlow::Incompleteness cause) {
123-
this instanceof Parameter and cause = "call"
123+
this instanceof Parameter and DataFlow::valueNode(this).(AnalyzedValueNode).isIncomplete(cause)
124124
or
125125
this instanceof ImportSpecifier and cause = "import"
126126
or
@@ -140,48 +140,59 @@ class AnalyzedVarDef extends VarDef {
140140
TopLevel getTopLevel() { result = this.(ASTNode).getTopLevel() }
141141
}
142142

143-
/**
144-
* Flow analysis for simple parameters of selected functions.
145-
*/
146-
private class AnalyzedParameter extends AnalyzedVarDef, @vardecl {
147-
AnalyzedParameter() {
148-
exists(FunctionWithAnalyzedParameters f, int parmIdx | this = f.getParameter(parmIdx) |
149-
// we cannot track flow into rest parameters
150-
not this.(Parameter).isRestParameter()
151-
)
152-
}
143+
private predicate isAnalyzedParameter(Parameter p) {
144+
exists(FunctionWithAnalyzedParameters f, int parmIdx | p = f.getParameter(parmIdx) |
145+
// we cannot track flow into rest parameters
146+
not p.(Parameter).isRestParameter()
147+
)
148+
}
153149

154-
/** Gets the function this is a parameter of. */
155-
FunctionWithAnalyzedParameters getFunction() { this = result.getAParameter() }
150+
private class AnalyzedParameter extends AnalyzedValueNode {
151+
override Parameter astNode;
156152

157-
override DataFlow::AnalyzedNode getRhs() {
158-
getFunction().argumentPassing(this, result.asExpr()) or
159-
result = AnalyzedVarDef.super.getRhs()
160-
}
153+
AnalyzedParameter() { isAnalyzedParameter(astNode) }
161154

162-
override AbstractValue getAnRhsValue() {
163-
result = AnalyzedVarDef.super.getAnRhsValue()
155+
FunctionWithAnalyzedParameters getFunction() { astNode = result.getAParameter() }
156+
157+
override AbstractValue getALocalValue() {
158+
exists(DataFlow::AnalyzedNode pred |
159+
getFunction().argumentPassing(astNode, pred.asExpr()) and
160+
result = pred.getALocalValue()
161+
)
164162
or
165-
not getFunction().mayReceiveArgument(this) and
163+
not getFunction().mayReceiveArgument(astNode) and
166164
result = TAbstractUndefined()
165+
or
166+
result = astNode.getDefault().analyze().getALocalValue()
167167
}
168168

169169
override predicate isIncomplete(DataFlow::Incompleteness cause) {
170170
getFunction().isIncomplete(cause)
171171
or
172-
not getFunction().argumentPassing(this, _) and
173-
getFunction().mayReceiveArgument(this) and
172+
not getFunction().argumentPassing(astNode, _) and
173+
getFunction().mayReceiveArgument(astNode) and
174174
cause = "call"
175175
}
176176
}
177177

178+
/**
179+
* Flow analysis for simple parameters of selected functions.
180+
*/
181+
private class AnalyzedParameterAsVarDef extends AnalyzedVarDef, @vardecl {
182+
AnalyzedParameterAsVarDef() { this instanceof Parameter }
183+
184+
override AbstractValue getAnRhsValue() {
185+
result = DataFlow::valueNode(this).(AnalyzedValueNode).getALocalValue()
186+
}
187+
}
188+
178189
/**
179190
* Flow analysis for simple rest parameters.
180191
*/
181-
private class AnalyzedRestParameter extends AnalyzedVarDef, @vardecl {
182-
AnalyzedRestParameter() { this.(Parameter).isRestParameter() }
192+
private class AnalyzedRestParameter extends AnalyzedValueNode {
193+
AnalyzedRestParameter() { astNode.(Parameter).isRestParameter() }
183194

184-
override AbstractValue getAnRhsValue() { result = TAbstractOtherObject() }
195+
override AbstractValue getALocalValue() { result = TAbstractOtherObject() }
185196

186197
override predicate isIncomplete(DataFlow::Incompleteness cause) { none() }
187198
}

0 commit comments

Comments
 (0)