JS: Fix callback check so it works without parameters

This commit is contained in:
Asger F
2024-11-21 09:23:38 +01:00
parent b7dd455aff
commit dcdb2e5133
2 changed files with 14 additions and 3 deletions

View File

@@ -8,6 +8,17 @@ private import semmle.javascript.dataflow.internal.AdditionalFlowInternal
private import semmle.javascript.dataflow.FlowSummary
private import semmle.javascript.internal.flow_summaries.Promises
private predicate isCallback(DataFlow::SourceNode node) {
node instanceof DataFlow::FunctionNode
or
node instanceof DataFlow::PartialInvokeNode
or
exists(DataFlow::SourceNode prev |
isCallback(prev) and
DataFlow::argumentPassingStep(_, prev.getALocalUse(), _, node)
)
}
/**
* Summary that propagates exceptions out of callbacks back to the caller.
*/
@@ -21,7 +32,7 @@ private class ExceptionFlowSummary extends SummarizedCallable {
["then", "catch", "finally", "addEventListener", EventEmitter::on()] and
not result = promiseConstructorRef().getAnInvocation() and
// Restrict to cases where a callback is known to flow in, as lambda flow in DataFlowImplCommon blows up otherwise
exists(result.getABoundCallbackParameter(_, _))
isCallback(result.getAnArgument().getALocalSource())
}
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {

View File

@@ -13,7 +13,7 @@ function e1() {
throw source('e1.3'); // Same as e1.2 but without callback parameters
});
} catch (err) {
sink(err); // $ hasValueFlow=e1.2 MISSING: hasValueFlow=e1.1 hasValueFlow=e1.3
sink(err); // $ hasValueFlow=e1.2 hasValueFlow=e1.3 MISSING: hasValueFlow=e1.1
}
}
@@ -47,7 +47,7 @@ function e3() {
throw source('e3.4');
});
} catch (err) {
sink(err); // $ MISSING: hasValueFlow=e3.4
sink(err); // $ hasValueFlow=e3.4
}
}