mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
JS: Also track into callbacks
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
private import javascript
|
||||
private import internal.FlowSteps
|
||||
private import internal.AccessPaths
|
||||
private import internal.CallGraphs
|
||||
|
||||
/**
|
||||
* A data flow tracking configuration for finding inter-procedural paths from
|
||||
@@ -620,10 +621,11 @@ private predicate exploratoryFlowStep(
|
||||
isAdditionalStoreStep(pred, succ, _, cfg) or
|
||||
isAdditionalLoadStep(pred, succ, _, cfg) or
|
||||
isAdditionalLoadStoreStep(pred, succ, _, cfg) or
|
||||
// the following two disjuncts taken together over-approximate flow through
|
||||
// the following three disjuncts taken together over-approximate flow through
|
||||
// higher-order calls
|
||||
callback(pred, succ) or
|
||||
succ = pred.(DataFlow::FunctionNode).getAParameter()
|
||||
succ = pred.(DataFlow::FunctionNode).getAParameter() or
|
||||
exploratoryBoundInvokeStep(pred, succ)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1032,6 +1034,13 @@ private predicate flowIntoHigherOrderCall(
|
||||
succ = cb.getParameter(i) and
|
||||
summary = oldSummary.append(PathSummary::call())
|
||||
)
|
||||
or
|
||||
exists(DataFlow::SourceNode cb, DataFlow::FunctionNode f, int i, int boundArgs, PathSummary oldSummary |
|
||||
higherOrderCall(pred, cb, i, cfg, oldSummary) and
|
||||
cb = CallGraph::getABoundFunctionReference(f, boundArgs, false) and
|
||||
succ = f.getParameter(boundArgs + i) and
|
||||
summary = oldSummary.append(PathSummary::call())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,6 +104,20 @@ private module CachedSteps {
|
||||
CallGraph::getABoundFunctionReference(f.flow(), boundArgs, false).flowsTo(invk.getCalleeNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred` may flow to `succ` through an invocation of a bound function.
|
||||
*
|
||||
* Should only be used for graph pruning, as the edge may lead to spurious flow.
|
||||
*/
|
||||
cached
|
||||
predicate exploratoryBoundInvokeStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::InvokeNode invk, DataFlow::FunctionNode f, int i, int boundArgs |
|
||||
CallGraph::getABoundFunctionReference(f, boundArgs, _).flowsTo(invk.getCalleeNode()) and
|
||||
pred = invk.getArgument(i) and
|
||||
succ = f.getParameter(i + boundArgs)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `invk` may invoke `f` indirectly through the given `callback` argument.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@ typeInferenceMismatch
|
||||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:22:10:22:10 | x |
|
||||
| bound-function.js:12:12:12:19 | source() | bound-function.js:4:10:4:10 | y |
|
||||
| bound-function.js:14:6:14:13 | source() | bound-function.js:4:10:4:10 | y |
|
||||
| bound-function.js:22:8:22:15 | source() | bound-function.js:25:10:25:10 | y |
|
||||
| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) |
|
||||
| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() |
|
||||
| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() |
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:22:10:22:10 | x |
|
||||
| bound-function.js:12:12:12:19 | source() | bound-function.js:4:10:4:10 | y |
|
||||
| bound-function.js:14:6:14:13 | source() | bound-function.js:4:10:4:10 | y |
|
||||
| bound-function.js:22:8:22:15 | source() | bound-function.js:25:10:25:10 | y |
|
||||
| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) |
|
||||
| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() |
|
||||
| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() |
|
||||
|
||||
@@ -19,7 +19,7 @@ foo2(null, source()); // OK
|
||||
|
||||
|
||||
function takesCallback(cb) {
|
||||
cb(source()); // NOT OK - but not found
|
||||
cb(source()); // NOT OK
|
||||
}
|
||||
function callback(x, y) {
|
||||
sink(y);
|
||||
|
||||
Reference in New Issue
Block a user