mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
JavaScript: Remove old data flow library.
This commit is contained in:
@@ -1,591 +0,0 @@
|
||||
/**
|
||||
* DEPRECATED: Use the new data flow library instead.
|
||||
*
|
||||
* Provides a class `DataFlowNode` for working with a data flow graph-based
|
||||
* program representation.
|
||||
*
|
||||
* We distinguish between _local flow_ and _non-local flow_.
|
||||
*
|
||||
* Local flow only considers three kinds of data flow:
|
||||
*
|
||||
* 1. Flow within an expression, for example from the operands of a `&&`
|
||||
* expression to the expression itself.
|
||||
* 2. Flow through local variables, that is, from definitions to uses.
|
||||
* Captured variables are treated flow-insensitively, that is, all
|
||||
* definitions are considered to flow to all uses, while for non-captured
|
||||
* variables only definitions that can actually reach a use are considered.
|
||||
* 3. Flow into and out of immediately invoked function expressions, that is,
|
||||
* flow from arguments to parameters, and from returned expressions to the
|
||||
* function expression itself.
|
||||
*
|
||||
* Non-local flow additionally tracks data flow through global variables.
|
||||
*
|
||||
* Flow through object properties or function calls is not modelled (except
|
||||
* for immediately invoked functions as explained above).
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `DataFlow::Node` instead.
|
||||
*
|
||||
* An expression or function/class declaration, viewed as a node in a data flow graph.
|
||||
*/
|
||||
deprecated class DataFlowNode extends @dataflownode {
|
||||
/**
|
||||
* Gets another flow node from which data may flow to this node in one local step.
|
||||
*/
|
||||
cached
|
||||
DataFlowNode localFlowPred() {
|
||||
// to be overridden by subclasses
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets another flow node from which data may flow to this node in one non-local step.
|
||||
*/
|
||||
DataFlowNode nonLocalFlowPred() {
|
||||
// to be overridden by subclasses
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets another flow node from which data may flow to this node in one step,
|
||||
* either locally or non-locally.
|
||||
*/
|
||||
DataFlowNode flowPred() { result = localFlowPred() or result = nonLocalFlowPred() }
|
||||
|
||||
/**
|
||||
* Gets a source flow node (that is, a node without a `localFlowPred()`) from which data
|
||||
* may flow to this node in zero or more local steps.
|
||||
*/
|
||||
cached
|
||||
deprecated DataFlowNode getALocalSource() {
|
||||
isLocalSource(result) and
|
||||
(
|
||||
result = this
|
||||
or
|
||||
locallyReachable(result, this)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a source flow node (that is, a node without a `flowPred()`) from which data
|
||||
* may flow to this node in zero or more steps, considering both local and non-local flow.
|
||||
*/
|
||||
DataFlowNode getASource() {
|
||||
if exists(flowPred()) then result = flowPred().getASource() else result = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the flow information for this node is incomplete.
|
||||
*
|
||||
* This predicate holds if there may be a source flow node from which data flows into
|
||||
* this node, but that node is not a result of `getASource()` due to analysis incompleteness.
|
||||
* The parameter `cause` is bound to a string describing the source of incompleteness.
|
||||
*
|
||||
* For example, since this analysis is intra-procedural, data flow from actual arguments
|
||||
* to formal parameters is not modeled. Hence, if `p` is an access to a parameter,
|
||||
* `p.getASource()` does _not_ return the corresponding argument, and
|
||||
* `p.isIncomplete("call")` holds.
|
||||
*/
|
||||
predicate isIncomplete(DataFlowIncompleteness cause) { none() }
|
||||
|
||||
/** Gets type inference results for this data flow node. */
|
||||
DataFlow::AnalyzedNode analyze() { result = DataFlow::valueNode(this).analyze() }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.(ASTNode).toString() }
|
||||
|
||||
/** Gets the location of the AST node underlying this data flow node. */
|
||||
Location getLocation() { result = this.(ASTNode).getLocation() }
|
||||
}
|
||||
|
||||
/** Holds if `nd` is a local source, that is, it has no local data flow predecessor. */
|
||||
deprecated private predicate isLocalSource(DataFlowNode nd) { not exists(nd.localFlowPred()) }
|
||||
|
||||
/** Holds if data may flom from `nd` to `succ` in one local step. */
|
||||
deprecated private predicate localFlow(DataFlowNode nd, DataFlowNode succ) {
|
||||
nd = succ.localFlowPred()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `snk` is reachable from `src` in one or more local steps, where `src`
|
||||
* itself is reachable from a local source in zere or more local steps.
|
||||
*/
|
||||
deprecated private predicate locallyReachable(DataFlowNode src, DataFlowNode snk) =
|
||||
boundedFastTC(localFlow/2, isLocalSource/1)(src, snk)
|
||||
|
||||
/**
|
||||
* A classification of flows that are not modeled, or only modeled incompletely, by
|
||||
* `DataFlowNode`.
|
||||
*/
|
||||
deprecated class DataFlowIncompleteness extends string {
|
||||
DataFlowIncompleteness() {
|
||||
this = "call" or // lack of inter-procedural analysis
|
||||
this = "heap" or // lack of heap modeling
|
||||
this = "import" or // lack of module import/export modeling
|
||||
this = "global" or // incomplete modeling of global object
|
||||
this = "yield" or // lack of yield/async/await modeling
|
||||
this = "eval" or // lack of reflection modeling
|
||||
this = "namespace" // lack of exported variable modeling
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable access, viewed as a data flow node.
|
||||
*/
|
||||
deprecated private class VarAccessFlow extends DataFlowNode, @varaccess {
|
||||
VarAccessFlow() { this instanceof RValue }
|
||||
|
||||
/**
|
||||
* Gets a data flow node representing a local variable definition to which
|
||||
* this access may refer.
|
||||
*/
|
||||
private VarDefFlow getALocalDef() {
|
||||
exists(SsaDefinition def |
|
||||
this = def.getVariable().getAUse() and
|
||||
result = def.getAContributingVarDef()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlowNode localFlowPred() {
|
||||
// flow through local variable
|
||||
result = getALocalDef().getSourceNode()
|
||||
}
|
||||
|
||||
override DataFlowNode nonLocalFlowPred() {
|
||||
exists(GlobalVariable v, VarDefFlow def |
|
||||
v = def.getAVariable() and
|
||||
result = def.getSourceNode() and
|
||||
this = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) {
|
||||
exists(SsaDefinition ssa, VarDefFlow def |
|
||||
this = ssa.getVariable().getAUse() and def = ssa.getAContributingVarDef()
|
||||
|
|
||||
def.isIncomplete(cause)
|
||||
)
|
||||
or
|
||||
exists(Variable v | this = v.getAnAccess() |
|
||||
v.isGlobal() and cause = "global"
|
||||
or
|
||||
globalIsIncomplete(v, cause)
|
||||
or
|
||||
v.isNamespaceExport() and cause = "namespace"
|
||||
or
|
||||
v instanceof ArgumentsVariable and cause = "call"
|
||||
or
|
||||
any(DirectEval e).mayAffect(v) and cause = "eval"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `v` has a definition that introduces analysis incompleteness due to
|
||||
* the given `cause`.
|
||||
*
|
||||
* We exclude cause `"global"`, since all global variables have this incompleteness anyway.
|
||||
*/
|
||||
pragma[noinline]
|
||||
deprecated private predicate globalIsIncomplete(GlobalVariable v, DataFlowIncompleteness cause) {
|
||||
exists(VarDefFlow def |
|
||||
v = def.getAVariable() and
|
||||
def.isIncomplete(cause) and
|
||||
cause != "global"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable definition, viewed as a contributor to the data flow graph.
|
||||
*/
|
||||
deprecated private class VarDefFlow extends VarDef {
|
||||
/**
|
||||
* Gets a data flow node representing the value assigned by this
|
||||
* definition.
|
||||
*/
|
||||
DataFlowNode getSourceNode() {
|
||||
// follow one step of the def-use chain, but only for definitions where
|
||||
// the lhs is a simple variable reference (as opposed to a destructuring
|
||||
// pattern)
|
||||
result = getSource() and getTarget() instanceof VarRef
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this definition is analyzed imprecisely due to `cause`.
|
||||
*/
|
||||
predicate isIncomplete(DataFlowIncompleteness cause) {
|
||||
this instanceof Parameter and cause = "call"
|
||||
or
|
||||
this instanceof ImportSpecifier and cause = "import"
|
||||
or
|
||||
exists(EnhancedForLoop efl | this = efl.getIteratorExpr()) and cause = "heap"
|
||||
or
|
||||
exists(ComprehensionBlock cb | this = cb.getIterator()) and cause = "yield"
|
||||
or
|
||||
getTarget() instanceof DestructuringPattern and cause = "heap"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An IIFE parameter, viewed as a contributor to the data flow graph.
|
||||
*/
|
||||
deprecated private class IifeParameterFlow extends VarDefFlow {
|
||||
/** The function of which this is a parameter. */
|
||||
ImmediatelyInvokedFunctionExpr iife;
|
||||
|
||||
IifeParameterFlow() {
|
||||
this instanceof SimpleParameter and
|
||||
iife.argumentPassing(this, _)
|
||||
}
|
||||
|
||||
override DataFlowNode getSourceNode() { iife.argumentPassing(this, result) }
|
||||
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An ECMAScript 2015 import, viewed as a contributor to the data flow graph.
|
||||
*/
|
||||
deprecated private class ImportSpecifierFlow extends VarDefFlow, ImportSpecifier {
|
||||
override DataFlowNode getSourceNode() { result = getLocal() }
|
||||
}
|
||||
|
||||
/** A parenthesized expression, viewed as a data flow node. */
|
||||
deprecated private class ParExprFlow extends DataFlowNode, @parexpr {
|
||||
override DataFlowNode localFlowPred() { result = this.(ParExpr).getExpression() }
|
||||
}
|
||||
|
||||
/** A type assertion, `E as T` or `<T> E`, viewed as a data flow node. */
|
||||
deprecated private class TypeAssertionFlow extends DataFlowNode, @typeassertion {
|
||||
override DataFlowNode localFlowPred() { result = this.(TypeAssertion).getExpression() }
|
||||
}
|
||||
|
||||
/** A non-null assertion, `E!` viewed as a data flow node. */
|
||||
deprecated private class NonNullAssertionFlow extends DataFlowNode, @non_null_assertion {
|
||||
override DataFlowNode localFlowPred() { result = this.(NonNullAssertion).getExpression() }
|
||||
}
|
||||
|
||||
/** An expression with type arguments, viewed as a data flow node. */
|
||||
deprecated private class ExpressionWithTypeArgumentsFlow extends DataFlowNode,
|
||||
@expressionwithtypearguments {
|
||||
override DataFlowNode localFlowPred() {
|
||||
result = this.(ExpressionWithTypeArguments).getExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/** A sequence expression, viewed as a data flow node. */
|
||||
deprecated private class SeqExprFlow extends DataFlowNode, @seqexpr {
|
||||
override DataFlowNode localFlowPred() { result = this.(SeqExpr).getLastOperand() }
|
||||
}
|
||||
|
||||
/** A short-circuiting logical expression, viewed as a data flow node. */
|
||||
deprecated private class LogicalBinaryExprFlow extends DataFlowNode, @binaryexpr {
|
||||
LogicalBinaryExprFlow() { this instanceof LogicalBinaryExpr }
|
||||
|
||||
override DataFlowNode localFlowPred() { result = this.(LogicalBinaryExpr).getAnOperand() }
|
||||
}
|
||||
|
||||
/** An assignment expression, viewed as a data flow node. */
|
||||
deprecated private class AssignExprFlow extends DataFlowNode, @assignexpr {
|
||||
override DataFlowNode localFlowPred() { result = this.(AssignExpr).getRhs() }
|
||||
}
|
||||
|
||||
/** A conditional expression, viewed as a data flow node. */
|
||||
deprecated private class ConditionalExprFlow extends DataFlowNode, @conditionalexpr {
|
||||
override DataFlowNode localFlowPred() { result = this.(ConditionalExpr).getABranch() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node whose value involves inter-procedural flow,
|
||||
* and which hence is analyzed incompletely.
|
||||
*/
|
||||
deprecated private class InterProcFlow extends DataFlowNode, @expr {
|
||||
InterProcFlow() {
|
||||
this instanceof InvokeExpr or
|
||||
this instanceof ThisExpr or
|
||||
this instanceof SuperExpr or
|
||||
this instanceof NewTargetExpr or
|
||||
this instanceof FunctionBindExpr or
|
||||
this instanceof TaggedTemplateExpr
|
||||
}
|
||||
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { cause = "call" }
|
||||
}
|
||||
|
||||
/** An external module reference, viewed as a data flow node. */
|
||||
deprecated private class ExternalModuleFlow extends DataFlowNode, @externalmodulereference {
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { cause = "import" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An immediately invoked function expression, viewed as a data flow node.
|
||||
*
|
||||
* Unlike other calls, we can analyze the value of an IIFE completely, hence
|
||||
* we override `InterProcFlow`.
|
||||
*/
|
||||
deprecated private class IifeFlow extends InterProcFlow, @callexpr {
|
||||
/** The function this IIFE invokes. */
|
||||
ImmediatelyInvokedFunctionExpr iife;
|
||||
|
||||
IifeFlow() { this = iife.getInvocation() }
|
||||
|
||||
override DataFlowNode localFlowPred() { result = iife.getAReturnedExpr() }
|
||||
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A property access, viewed as a data flow node.
|
||||
*/
|
||||
deprecated private class PropAccessFlow extends DataFlowNode, @propaccess {
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { cause = "heap" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node whose value involves co-routines or promises,
|
||||
* and which hence is analyzed incompletely.
|
||||
*/
|
||||
deprecated private class IteratorFlow extends DataFlowNode, @expr {
|
||||
IteratorFlow() {
|
||||
this instanceof YieldExpr or
|
||||
this instanceof AwaitExpr or
|
||||
this instanceof FunctionSentExpr or
|
||||
this instanceof DynamicImportExpr
|
||||
}
|
||||
|
||||
override predicate isIncomplete(DataFlowIncompleteness cause) { cause = "yield" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that reads or writes an object property.
|
||||
*/
|
||||
abstract deprecated class PropRefNode extends DataFlowNode {
|
||||
/**
|
||||
* Gets the data flow node corresponding to the base object
|
||||
* whose property is read from or written to.
|
||||
*/
|
||||
abstract DataFlowNode getBase();
|
||||
|
||||
/**
|
||||
* Gets the expression specifying the name of the property being
|
||||
* read or written. This is usually either an identifier or a literal.
|
||||
*/
|
||||
abstract Expr getPropertyNameExpr();
|
||||
|
||||
/**
|
||||
* Gets the name of the property being read or written,
|
||||
* if it can be statically determined.
|
||||
*
|
||||
* This predicate is undefined for dynamic property references
|
||||
* such as `e[computePropertyName()]` and for spread/rest
|
||||
* properties.
|
||||
*/
|
||||
abstract string getPropertyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that writes to an object property.
|
||||
*/
|
||||
abstract deprecated class PropWriteNode extends PropRefNode {
|
||||
/**
|
||||
* Gets the data flow node corresponding to the value being written,
|
||||
* if it can be statically determined.
|
||||
*
|
||||
* This predicate is undefined for spread properties, accessor
|
||||
* properties, and most uses of `Object.defineProperty`.
|
||||
*/
|
||||
abstract DataFlowNode getRhs();
|
||||
|
||||
/**
|
||||
* Holds if this data flow node writes the value of `rhs` to property
|
||||
* `prop` of the object that `base` evaluates to.
|
||||
*/
|
||||
pragma[noinline]
|
||||
predicate writes(DataFlow::Node base, string prop, DataFlow::Node rhs) {
|
||||
base = DataFlow::valueNode(getBase()) and
|
||||
prop = getPropertyName() and
|
||||
rhs = DataFlow::valueNode(getRhs())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A property assignment, viewed as a data flow node.
|
||||
*/
|
||||
deprecated private class PropAssignNode extends PropWriteNode, @propaccess {
|
||||
PropAssignNode() { this instanceof LValue }
|
||||
|
||||
override DataFlowNode getBase() { result = this.(PropAccess).getBase() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = this.(PropAccess).getPropertyNameExpr() }
|
||||
|
||||
override string getPropertyName() { result = this.(PropAccess).getPropertyName() }
|
||||
|
||||
override DataFlowNode getRhs() { result = this.(LValue).getRhs() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A property of an object literal, viewed as a data flow node that writes
|
||||
* to the corresponding property.
|
||||
*/
|
||||
deprecated private class PropInitNode extends PropWriteNode, @property {
|
||||
/** Gets the property that this node wraps. */
|
||||
private Property getProperty() { result = this }
|
||||
|
||||
override DataFlowNode getBase() { result = getProperty().getObjectExpr() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = getProperty().getNameExpr() }
|
||||
|
||||
override string getPropertyName() { result = getProperty().getName() }
|
||||
|
||||
override DataFlowNode getRhs() { result = getProperty().(ValueProperty).getInit() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `Object.defineProperty`, viewed as a data flow node that
|
||||
* writes to the corresponding property.
|
||||
*/
|
||||
deprecated private class ObjectDefinePropNode extends PropWriteNode, @callexpr {
|
||||
CallToObjectDefineProperty odp;
|
||||
|
||||
ObjectDefinePropNode() { this = odp.asExpr() }
|
||||
|
||||
override DataFlowNode getBase() { result = odp.getBaseObject().asExpr() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = odp.getArgument(1).asExpr() }
|
||||
|
||||
override string getPropertyName() { result = odp.getPropertyName() }
|
||||
|
||||
override DataFlowNode getRhs() {
|
||||
exists(ObjectExpr propdesc |
|
||||
propdesc = odp.getPropertyDescriptor().asExpr() and
|
||||
result = propdesc.getPropertyByName("value").getInit()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A static member definition, viewed as a data flow node that adds
|
||||
* a property to the class.
|
||||
*/
|
||||
deprecated private class StaticMemberAsWrite extends PropWriteNode, @expr {
|
||||
StaticMemberAsWrite() { exists(MemberDefinition md | md.isStatic() and this = md.getNameExpr()) }
|
||||
|
||||
/** Gets the member definition that this node wraps. */
|
||||
private MemberDefinition getMember() { this = result.getNameExpr() }
|
||||
|
||||
override DataFlowNode getBase() { result = getMember().getDeclaringClass() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = getMember().getNameExpr() }
|
||||
|
||||
override string getPropertyName() { result = getMember().getName() }
|
||||
|
||||
override DataFlowNode getRhs() { result = getMember().getInit() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A spread property of an object literal, viewed as a data flow node that writes
|
||||
* properties of the object literal.
|
||||
*/
|
||||
deprecated private class SpreadPropertyAsWrite extends PropWriteNode, @expr {
|
||||
SpreadPropertyAsWrite() { exists(SpreadProperty prop | this = prop.getInit()) }
|
||||
|
||||
override DataFlowNode getBase() { result.(ObjectExpr).getAProperty().getInit() = this }
|
||||
|
||||
override Expr getPropertyNameExpr() { none() }
|
||||
|
||||
override string getPropertyName() { none() }
|
||||
|
||||
override DataFlowNode getRhs() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A JSX attribute, viewed as a data flow node that writes properties to
|
||||
* the JSX element it is in.
|
||||
*/
|
||||
deprecated private class JSXAttributeAsWrite extends PropWriteNode, @identifier {
|
||||
JSXAttributeAsWrite() { exists(JSXAttribute attr | this = attr.getNameExpr()) }
|
||||
|
||||
/** Gets the JSX attribute that this node wraps. */
|
||||
private JSXAttribute getAttribute() { result.getNameExpr() = this }
|
||||
|
||||
override DataFlowNode getBase() { result = getAttribute().getElement() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = this }
|
||||
|
||||
override string getPropertyName() { result = this.(Identifier).getName() }
|
||||
|
||||
override DataFlowNode getRhs() { result = getAttribute().getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that reads an object property.
|
||||
*/
|
||||
abstract deprecated class PropReadNode extends PropRefNode {
|
||||
/**
|
||||
* Gets the default value of this property read, if any.
|
||||
*/
|
||||
abstract DataFlowNode getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* A property access in rvalue position.
|
||||
*/
|
||||
deprecated private class PropAccessReadNode extends PropReadNode, @propaccess {
|
||||
PropAccessReadNode() { this instanceof RValue }
|
||||
|
||||
override DataFlowNode getBase() { result = this.(PropAccess).getBase() }
|
||||
|
||||
override Expr getPropertyNameExpr() { result = this.(PropAccess).getPropertyNameExpr() }
|
||||
|
||||
override string getPropertyName() { result = this.(PropAccess).getPropertyName() }
|
||||
|
||||
override DataFlowNode getDefault() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A property pattern viewed as a property read; for instance, in
|
||||
* `var { p: q } = o`, `p` is a read of property `p` of `o`.
|
||||
*/
|
||||
deprecated private class PropPatternReadNode extends PropReadNode, @expr {
|
||||
PropPatternReadNode() { this = any(PropertyPattern p).getNameExpr() }
|
||||
|
||||
/** Gets the property pattern that this node wraps. */
|
||||
private PropertyPattern getPropertyPattern() { this = result.getNameExpr() }
|
||||
|
||||
override DataFlowNode getBase() {
|
||||
exists(VarDef d |
|
||||
d.getTarget() = getPropertyPattern().getObjectPattern() and
|
||||
result = d.getSource()
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getPropertyNameExpr() { result = getPropertyPattern().getNameExpr() }
|
||||
|
||||
override string getPropertyName() { result = getPropertyPattern().getName() }
|
||||
|
||||
override DataFlowNode getDefault() { result = getPropertyPattern().getDefault() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A rest pattern viewed as a property read; for instance, in
|
||||
* `var { ...ps } = o`, `ps` is a read of all properties of `o`.
|
||||
*/
|
||||
deprecated private class RestPropertyAsRead extends PropReadNode {
|
||||
RestPropertyAsRead() { this = any(ObjectPattern p).getRest() }
|
||||
|
||||
override DataFlowNode getBase() {
|
||||
exists(VarDef d |
|
||||
d.getTarget().(ObjectPattern).getRest() = this and
|
||||
result = d.getSource()
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getPropertyNameExpr() { none() }
|
||||
|
||||
override string getPropertyName() { none() }
|
||||
|
||||
override DataFlowNode getDefault() { none() }
|
||||
}
|
||||
@@ -172,62 +172,3 @@ abstract class PathExprInModule extends PathExpr {
|
||||
getEnclosingModule().searchRoot(this, result, priority)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An import of a module with the given `path`, either using `require` or using `import`.
|
||||
*/
|
||||
deprecated private predicate isImport(DataFlowNode nd, string moduleName) {
|
||||
exists(Import i | i.getImportedPath().getValue() = moduleName |
|
||||
// `require("http")`
|
||||
nd = i.(Require)
|
||||
or
|
||||
exists(ImportSpecifier spec | spec = i.(ImportDeclaration).getASpecifier() |
|
||||
// common, but semantically different, ways of exposing modules through imports:
|
||||
// `import * as http from 'http'`
|
||||
nd = spec.(ImportNamespaceSpecifier).getLocal()
|
||||
or
|
||||
// `import http from 'http'`
|
||||
nd = spec.(ImportDefaultSpecifier).getLocal()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `DataFlow::moduleImport` and `DataFlow::ModuleImportNode` instead.
|
||||
*
|
||||
* A data flow node that holds a module instance, that is, the result of
|
||||
* an import of the module.
|
||||
*/
|
||||
deprecated class ModuleInstance extends DataFlowNode {
|
||||
ModuleInstance() { isImport(this, _) }
|
||||
|
||||
/** Gets the path from which the module is imported. */
|
||||
string getPath() { isImport(this, result) }
|
||||
|
||||
/**
|
||||
* Gets an invocation of the method or constructor named `memberName` on this module instance.
|
||||
*/
|
||||
InvokeExpr getAMemberInvocation(string memberName) {
|
||||
result.getCallee().(DataFlowNode).getALocalSource() = getAPropertyRead(memberName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a function call that invokes method `methodName` on this module instance.
|
||||
*/
|
||||
CallExpr getAMethodCall(string methodName) { result = getAMemberInvocation(methodName) }
|
||||
|
||||
/**
|
||||
* Gets a `new` call that invokes constructor `constructorName` on this module instance.
|
||||
*/
|
||||
NewExpr getAConstructorInvocation(string constructorName) {
|
||||
result = getAMemberInvocation(constructorName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a read access to property `propName` on this module instance.
|
||||
*/
|
||||
PropReadNode getAPropertyRead(string propName) {
|
||||
result.getBase().getALocalSource() = this and
|
||||
result.getPropertyName() = propName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@ DataFlow::SourceNode angular() {
|
||||
result = DataFlow::moduleImport("angular")
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `angular()` instead.
|
||||
*/
|
||||
deprecated predicate isAngularRef(DataFlowNode nd) { angular().flowsToExpr(nd) }
|
||||
|
||||
pragma[noopt]
|
||||
private predicate isAngularString(Expr s) {
|
||||
exists(DataFlow::SourceNode angular, StmtContainer sc, TopLevel tl |
|
||||
|
||||
@@ -13,11 +13,6 @@ DataFlow::SourceNode react() {
|
||||
result = DataFlow::moduleImport("react")
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `react()` instead.
|
||||
*/
|
||||
deprecated predicate isReactRef(DataFlowNode nd) { react().flowsToExpr(nd) }
|
||||
|
||||
/**
|
||||
* An object that implements the React component interface.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user