зеркало из https://github.com/github/codeql.git
JS: Also propagate out of returns
This commit is contained in:
Родитель
8c36b999cc
Коммит
e8e649102f
|
@ -751,7 +751,7 @@ private predicate flowThroughCall(
|
|||
) {
|
||||
exists(Function f, DataFlow::ValueNode ret |
|
||||
ret.asExpr() = f.getAReturnedExpr() and
|
||||
calls(output, f) and // Do not consider partial calls
|
||||
(calls(output, f) or callsBound(output, f, _)) and // Do not consider partial calls
|
||||
reachableFromInput(f, output, input, ret, cfg, summary) and
|
||||
not isBarrierEdge(cfg, ret, output) and
|
||||
not isLabeledBarrierEdge(cfg, ret, output, summary.getEndLabel()) and
|
||||
|
@ -761,7 +761,7 @@ private predicate flowThroughCall(
|
|||
exists(Function f, DataFlow::Node invk, DataFlow::Node ret |
|
||||
DataFlow::exceptionalFunctionReturnNode(ret, f) and
|
||||
DataFlow::exceptionalInvocationReturnNode(output, invk.asExpr()) and
|
||||
calls(invk, f) and
|
||||
(calls(invk, f) or callsBound(invk, f, _)) and
|
||||
reachableFromInput(f, invk, input, ret, cfg, summary) and
|
||||
not isBarrierEdge(cfg, ret, output) and
|
||||
not isLabeledBarrierEdge(cfg, ret, output, summary.getEndLabel()) and
|
||||
|
|
|
@ -179,7 +179,7 @@ private module CachedSteps {
|
|||
*/
|
||||
cached
|
||||
predicate returnStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(Function f | calls(succ, f) |
|
||||
exists(Function f | calls(succ, f) or callsBound(succ, f, _) |
|
||||
returnExpr(f, pred, _)
|
||||
or
|
||||
succ instanceof DataFlow::NewNode and
|
||||
|
@ -188,8 +188,11 @@ private module CachedSteps {
|
|||
or
|
||||
exists(InvokeExpr invoke, Function fun |
|
||||
DataFlow::exceptionalFunctionReturnNode(pred, fun) and
|
||||
DataFlow::exceptionalInvocationReturnNode(succ, invoke) and
|
||||
DataFlow::exceptionalInvocationReturnNode(succ, invoke)
|
||||
|
|
||||
calls(invoke.flow(), fun)
|
||||
or
|
||||
callsBound(invoke.flow(), fun, _)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -485,4 +488,3 @@ module PathSummary {
|
|||
*/
|
||||
PathSummary return() { exists(FlowLabel lbl | result = MkPathSummary(true, false, lbl, lbl)) }
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ typeInferenceMismatch
|
|||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:13:10:13:10 | x |
|
||||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:19:10:19:10 | x |
|
||||
| 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: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() |
|
||||
| callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x |
|
||||
| callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x |
|
||||
| callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x |
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:13:10:13:10 | x |
|
||||
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:19:10:19:10 | x |
|
||||
| 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: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() |
|
||||
| callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x |
|
||||
| callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x |
|
||||
| callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x |
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import * as dummy from 'dummy';
|
||||
|
||||
function foo(x, y) {
|
||||
sink(y);
|
||||
}
|
||||
|
||||
let foo0 = foo.bind(null);
|
||||
let foo1 = foo.bind(null, null);
|
||||
let foo2 = foo.bind(null, null, null);
|
||||
|
||||
foo0(source(), null); // OK
|
||||
foo0(null, source()); // NOT OK
|
||||
|
||||
foo1(source()); // NOT OK
|
||||
foo1(null, source()); // OK
|
||||
|
||||
foo2(source()); // OK
|
||||
foo2(null, source()); // OK
|
||||
|
||||
|
||||
function takesCallback(cb) {
|
||||
cb(source()); // NOT OK - but not found
|
||||
}
|
||||
function callback(x, y) {
|
||||
sink(y);
|
||||
}
|
||||
takesCallback(callback.bind(null, null));
|
||||
|
||||
function id(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
let sourceGetter = id.bind(null, source());
|
||||
let constGetter = id.bind(null, 'safe');
|
||||
|
||||
sink(sourceGetter()); // NOT OK - but not flagged
|
||||
sink(constGetter()); // OK
|
||||
|
||||
function id2(x, y) {
|
||||
return y;
|
||||
}
|
||||
|
||||
let id3 = id2.bind(null, null);
|
||||
|
||||
sink(id3(source())); // NOT OK
|
||||
sink(id3('safe')); // OK
|
||||
|
||||
function getSource() {
|
||||
return source();
|
||||
}
|
||||
let source0 = getSource.bind(null);
|
||||
let source1 = getSource.bind(null, null);
|
||||
|
||||
sink(source0()); // NOT OK
|
||||
sink(source1()); // NOT OK
|
Загрузка…
Ссылка в новой задаче