mirror of
https://github.com/github/codeql.git
synced 2025-12-16 08:43:11 +01:00
JS: Avoid more bad joins due to locality
This commit is contained in:
@@ -477,6 +477,8 @@ module AST {
|
||||
DataFlow::AnalyzedNode analyze() { result = DataFlow::valueNode(this).analyze() }
|
||||
|
||||
/** Gets the data flow node associated with this program element. */
|
||||
overlay[caller]
|
||||
pragma[inline]
|
||||
DataFlow::ValueNode flow() { result = DataFlow::valueNode(this) }
|
||||
|
||||
/**
|
||||
|
||||
@@ -1016,7 +1016,7 @@ overlay[global]
|
||||
pragma[inline]
|
||||
private predicate isUsedAsNumber(DataFlow::LocalSourceNode value) {
|
||||
any(Comparison compare)
|
||||
.hasOperands(value.getALocalUse().asExpr(), any(Expr e | e.analyze().getAType() = TTNumber()))
|
||||
.hasOperands(value.getALocalUse().asExpr(), any(Expr e | canBeNumber(e.analyze())))
|
||||
or
|
||||
value.flowsToExpr(any(ArithmeticExpr e).getAnOperand())
|
||||
or
|
||||
@@ -1031,6 +1031,16 @@ private predicate isUsedAsNumber(DataFlow::LocalSourceNode value) {
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[node]
|
||||
overlay[global]
|
||||
pragma[inline_late]
|
||||
private predicate canBeString(DataFlow::AnalyzedNode node) { node.getAType() = TTString() }
|
||||
|
||||
bindingset[node]
|
||||
overlay[global]
|
||||
pragma[inline_late]
|
||||
private predicate canBeNumber(DataFlow::AnalyzedNode node) { node.getAType() = TTNumber() }
|
||||
|
||||
/**
|
||||
* Holds if `source` may be interpreted as a regular expression.
|
||||
*/
|
||||
@@ -1038,14 +1048,14 @@ overlay[global]
|
||||
cached
|
||||
predicate isInterpretedAsRegExp(DataFlow::Node source) {
|
||||
Stages::Taint::ref() and
|
||||
source.analyze().getAType() = TTString() and
|
||||
canBeString(source) and
|
||||
(
|
||||
// The first argument to an invocation of `RegExp` (with or without `new`).
|
||||
source = DataFlow::globalVarRef("RegExp").getAnInvocation().getArgument(0)
|
||||
or
|
||||
// The argument of a call that coerces the argument to a regular expression.
|
||||
exists(DataFlow::MethodCallNode mce, string methodName |
|
||||
mce.getReceiver().analyze().getAType() = TTString() and
|
||||
canBeString(mce.getReceiver()) and
|
||||
mce.getMethodName() = methodName and
|
||||
not exists(Function func | func = mce.getACallee() |
|
||||
not isNativeStringMethod(func, methodName)
|
||||
|
||||
@@ -1431,6 +1431,7 @@ module DataFlow {
|
||||
* This predicate is only defined for expressions, properties, and for statements that declare
|
||||
* a function, a class, or a TypeScript namespace or enum.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
ValueNode valueNode(AstNode nd) { result.getAstNode() = nd }
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ module LazyCache {
|
||||
pragma[noopt]
|
||||
override DataFlow::Node getImportedModuleNode() {
|
||||
this instanceof LazyCacheImport and
|
||||
result = this.flow()
|
||||
result = DataFlow::valueNode(this)
|
||||
or
|
||||
exists(LazyCacheVariable variable, Expr base, PropAccess access, string localName |
|
||||
// To avoid recursion, this should not depend on `SourceNode`.
|
||||
@@ -54,7 +54,7 @@ module LazyCache {
|
||||
access.getBase() = base and
|
||||
localName = this.getLocalAlias() and
|
||||
access.getPropertyName() = localName and
|
||||
result = access.flow()
|
||||
result = DataFlow::valueNode(access)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,18 @@ class ForOfLoopStep extends AdditionalFlowInternal {
|
||||
) {
|
||||
exists(ForOfStmt stmt |
|
||||
pred = getSynthesizedNode(stmt, "for-of-map-key") and
|
||||
contents.asSingleton().asArrayIndex() = 0
|
||||
contents = arrayIndex0()
|
||||
or
|
||||
pred = getSynthesizedNode(stmt, "for-of-map-value") and
|
||||
contents.asSingleton().asArrayIndex() = 1
|
||||
contents = arrayIndex1()
|
||||
|
|
||||
succ = DataFlow::lvalueNode(stmt.getLValue())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private DataFlow::ContentSet arrayIndex0() { result.asSingleton().asArrayIndex() = 0 }
|
||||
|
||||
pragma[nomagic]
|
||||
private DataFlow::ContentSet arrayIndex1() { result.asSingleton().asArrayIndex() = 1 }
|
||||
|
||||
Reference in New Issue
Block a user