Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aded18b

Browse files
committed
JS: Add DataFlow::Node.getImmediatePredecessor()
1 parent c97b9af commit aded18b

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,60 @@ module DataFlow {
161161

162162
/** Gets a textual representation of this element. */
163163
string toString() { none() }
164+
165+
/**
166+
* Gets the immediate predecessor of this node, if any.
167+
*
168+
* A node with an immediate predecessor can only ever have the value that flows
169+
* into its from its immediate predecessor. It can be treated as an alias for
170+
* the immediate predecessor.
171+
*/
172+
cached
173+
DataFlow::Node getImmediatePredecessor() {
174+
// Use of variable -> definition of variable
175+
exists(SsaVariable var |
176+
this = DataFlow::valueNode(var.getAUse()) and
177+
result.(DataFlow::SsaDefinitionNode).getSsaVariable() = var
178+
)
179+
or
180+
// Refinement of variable -> original definition of variable
181+
exists(SsaRefinementNode refinement |
182+
this.(DataFlow::SsaDefinitionNode).getSsaVariable() = refinement.getVariable() and
183+
result.(DataFlow::SsaDefinitionNode).getSsaVariable() = refinement.getAnInput()
184+
)
185+
or
186+
// Definition of variable -> RHS of definition
187+
exists(SsaExplicitDefinition def |
188+
this = TSsaDefNode(def) and
189+
result = def.getRhsNode()
190+
)
191+
or
192+
// IIFE call -> return value of IIFE
193+
// Note: not sound in case function falls over end and returns 'undefined'
194+
exists(Function fun |
195+
localCall(this.asExpr(), fun) and
196+
result = fun.getAReturnedExpr().flow() and
197+
strictcount(fun.getAReturnedExpr()) = 1
198+
)
199+
or
200+
// IIFE parameter -> IIFE call
201+
exists(Parameter param |
202+
this = DataFlow::parameterNode(param) and
203+
localArgumentPassing(result.asExpr(), param)
204+
)
205+
or
206+
// `{ x } -> e` in `let { x } = e`
207+
exists(DestructuringPattern pattern |
208+
this = TDestructuringPatternNode(pattern)
209+
|
210+
exists(VarDef def |
211+
pattern = def.getTarget() and
212+
result = DataFlow::valueNode(def.getDestructuringSource())
213+
)
214+
or
215+
result = patternPropRead(pattern)
216+
)
217+
}
164218
}
165219

166220
/**

0 commit comments

Comments
 (0)