JS: Summarize steps into captured variables

This commit is contained in:
Asger Feldthaus
2021-07-02 13:42:42 +02:00
parent 093ff41170
commit 457ce14ca6
4 changed files with 27 additions and 0 deletions

View File

@@ -1183,6 +1183,13 @@ private predicate flowThroughCall(
not cfg.isLabeledBarrier(output, summary.getEndLabel())
)
or
exists(Function f, LocalVariable variable |
reachableFromInput(f, _, input, output, cfg, summary) and
output = DataFlow::capturedVariableNode(variable) and
getCapturedVariableDepth(variable) < getContainerDepth(f) and // Only step outwards
not cfg.isLabeledBarrier(output, summary.getEndLabel())
)
or
exists(Function f, DataFlow::Node invk, DataFlow::Node ret |
DataFlow::exceptionalFunctionReturnNode(ret, f) and
DataFlow::exceptionalInvocationReturnNode(output, invk.asExpr()) and

View File

@@ -109,6 +109,22 @@ DataFlow::Node getThrowTarget(DataFlow::Node thrower) {
*/
cached
private module CachedSteps {
/** Gets the nesting depth of the given container, starting with the top-level at 0. */
cached
int getContainerDepth(StmtContainer container) {
not exists(container.getEnclosingContainer()) and
result = 0
or
result = 1 + getContainerDepth(container.getEnclosingContainer())
}
/** Gets the nesting depth of the container declaring the given captured variable. */
cached
int getCapturedVariableDepth(LocalVariable v) {
v.isCaptured() and
result = getContainerDepth(v.getDeclaringContainer())
}
/**
* Holds if `f` captures the given `variable` in `cap`.
*/