mirror of
https://github.com/github/codeql.git
synced 2026-04-11 10:04:02 +02:00
JS: Add FunctionSelfReferenceNode
This commit is contained in:
@@ -1888,6 +1888,8 @@ module PathNode {
|
||||
or
|
||||
// Skip captured variable nodes as the successor will be a use of that variable anyway.
|
||||
nd = DataFlow::capturedVariableNode(_)
|
||||
or
|
||||
nd instanceof DataFlow::FunctionSelfReferenceNode
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1432,6 +1432,30 @@ module DataFlow {
|
||||
override StmtContainer getContainer() { result = this.getTag().getInnerTopLevel() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing the hidden parameter of a function by which a function can refer to itself.
|
||||
*/
|
||||
class FunctionSelfReferenceNode extends DataFlow::Node, TFunctionSelfReferenceNode {
|
||||
private Function function;
|
||||
|
||||
FunctionSelfReferenceNode() { this = TFunctionSelfReferenceNode(function) }
|
||||
|
||||
/** Gets the function. */
|
||||
Function getFunction() { result = function }
|
||||
|
||||
override StmtContainer getContainer() { result = function }
|
||||
|
||||
override BasicBlock getBasicBlock() { result = function.getEntryBB() }
|
||||
|
||||
override string toString() { result = "[function self-reference] " + function.toString() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A post-update node whose pre-node corresponds to an expression. See `DataFlow::PostUpdateNode` for more details.
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@ private module Cached {
|
||||
(kind = "call" or kind = "apply")
|
||||
} or
|
||||
TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel } or
|
||||
TFunctionSelfReferenceNode(Function f) or
|
||||
TDestructuredModuleImportNode(ImportDeclaration decl) {
|
||||
exists(decl.getASpecifier().getImportedName())
|
||||
} or
|
||||
|
||||
@@ -152,6 +152,8 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition
|
||||
n = call.asBoundCall(boundArgs).getArgument(pos.asPositional() - boundArgs)
|
||||
)
|
||||
or
|
||||
pos.isFunctionSelfReference() and n = call.asOrdinaryCall().getCalleeNode()
|
||||
or
|
||||
pos.isThis() and n = TConstructorThisArgumentNode(call.asOrdinaryCall().asExpr())
|
||||
or
|
||||
// For now, treat all spread argument as flowing into the 'arguments' array, regardless of preceding arguments
|
||||
@@ -348,6 +350,7 @@ newtype TParameterPosition =
|
||||
MkPositionalParameter(int n) { n = [0 .. getMaxArity()] } or
|
||||
MkPositionalLowerBound(int n) { n = [0 .. getMaxArity()] } or
|
||||
MkThisParameter() or
|
||||
MkFunctionSelfReferenceParameter() or
|
||||
MkArgumentsArrayParameter()
|
||||
|
||||
class ParameterPosition extends TParameterPosition {
|
||||
@@ -363,6 +366,8 @@ class ParameterPosition extends TParameterPosition {
|
||||
|
||||
predicate isThis() { this = MkThisParameter() }
|
||||
|
||||
predicate isFunctionSelfReference() { this = MkFunctionSelfReferenceParameter() }
|
||||
|
||||
predicate isArgumentsArray() { this = MkArgumentsArrayParameter() }
|
||||
|
||||
string toString() {
|
||||
@@ -372,6 +377,8 @@ class ParameterPosition extends TParameterPosition {
|
||||
or
|
||||
this.isThis() and result = "this"
|
||||
or
|
||||
this.isFunctionSelfReference() and result = "function"
|
||||
or
|
||||
this.isArgumentsArray() and result = "arguments-array"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user