Skip to content

Commit dc2d6a5

Browse files
committed
JS: Make ValueNode the ParameterNode with a step to the SSA node
1 parent 37ddccf commit dc2d6a5

4 files changed

Lines changed: 31 additions & 36 deletions

File tree

javascript/ql/src/semmle/javascript/dataflow/Configuration.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,9 @@ class MidPathNode extends PathNode, MkMidNode {
16011601
nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof
16021602
SsaImplicitDefinition
16031603
or
1604+
// Skip SSA definition of parameter as its location coincides with the parameter node
1605+
nd = DataFlow::ssaDefinitionNode(SSA::definition(any(SimpleParameter p)))
1606+
or
16041607
// Skip to the top of big left-leaning string concatenation trees.
16051608
nd = any(AddExpr add).flow() and
16061609
nd = any(AddExpr add).getAnOperand().flow()

javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -713,10 +713,6 @@ module DataFlow {
713713
parameterNode(paramNode, param)
714714
|
715715
result = paramNode
716-
or
717-
// special case: there is no SSA flow step for unused parameters
718-
paramNode instanceof UnusedParameterNode and
719-
result = param.getDefault().flow()
720716
)
721717
}
722718

@@ -877,32 +873,6 @@ module DataFlow {
877873
override string getPropertyName() { none() }
878874
}
879875

880-
/**
881-
* A data flow node representing an unused parameter.
882-
*
883-
* This case exists to ensure all parameters have a corresponding data-flow node.
884-
* In most cases, parameters are represented by SSA definitions or destructuring pattern nodes.
885-
*/
886-
private class UnusedParameterNode extends DataFlow::Node, TUnusedParameterNode {
887-
SimpleParameter p;
888-
889-
UnusedParameterNode() { this = TUnusedParameterNode(p) }
890-
891-
override string toString() { result = p.toString() }
892-
893-
override ASTNode getAstNode() { result = p }
894-
895-
override BasicBlock getBasicBlock() { result = p.getBasicBlock() }
896-
897-
override predicate hasLocationInfo(
898-
string filepath, int startline, int startcolumn, int endline, int endcolumn
899-
) {
900-
p.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
901-
}
902-
903-
override File getFile() { result = p.getFile() }
904-
}
905-
906876
/**
907877
* A data flow node representing an HTML attribute.
908878
*/
@@ -1256,7 +1226,9 @@ module DataFlow {
12561226
/**
12571227
* INTERNAL: Use `parameterNode(Parameter)` instead.
12581228
*/
1259-
predicate parameterNode(DataFlow::Node nd, Parameter p) { nd = lvalueNode(p) }
1229+
predicate parameterNode(DataFlow::Node nd, Parameter p) {
1230+
nd = valueNode(p)
1231+
}
12601232

12611233
/**
12621234
* INTERNAL: Use `thisNode(StmtContainer container)` instead.
@@ -1309,8 +1281,6 @@ module DataFlow {
13091281
)
13101282
or
13111283
result = TValueNode(lvalue.(DestructuringPattern))
1312-
or
1313-
result = TUnusedParameterNode(lvalue)
13141284
}
13151285

13161286
/**
@@ -1365,6 +1335,11 @@ module DataFlow {
13651335
succ = lvalueNode(def.getTarget())
13661336
)
13671337
or
1338+
exists(SimpleParameter param |
1339+
pred = valueNode(param) and // The value node represents the incoming argument
1340+
succ = lvalueNode(param) // The SSA node represents the parameters's local variable
1341+
)
1342+
or
13681343
exists(PropertyPattern pattern |
13691344
pred = TPropNode(pattern) and
13701345
succ = lvalueNode(pattern.getValuePattern())
@@ -1576,8 +1551,6 @@ module DataFlow {
15761551
exists(PropertyPattern p | nd = TPropNode(p)) and cause = "heap"
15771552
or
15781553
nd instanceof TElementPatternNode and cause = "heap"
1579-
or
1580-
nd instanceof UnusedParameterNode and cause = "call"
15811554
}
15821555

15831556
/**

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,23 @@ 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/DataFlowNode.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ newtype TNode =
2222
(kind = "call" or kind = "apply")
2323
} or
2424
TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or
25-
TUnusedParameterNode(SimpleParameter p) { not exists(SSA::definition(p)) } or
2625
TDestructuredModuleImportNode(ImportDeclaration decl) {
2726
exists(decl.getASpecifier().getImportedName())
2827
} or

0 commit comments

Comments
 (0)