Skip to content

Commit 90422fe

Browse files
committed
add support for delegating yield
1 parent 6a07e1e commit 90422fe

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

javascript/ql/src/semmle/javascript/Generators.qll

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ private module GeneratorDataFlow {
1111
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
1212
exists(DataFlow::FunctionNode f | f.getFunction().isGenerator() |
1313
prop = iteratorElement() and
14-
exists(YieldExpr yield | yield.getContainer() = f.getFunction() |
14+
exists(YieldExpr yield |
15+
yield.getContainer() = f.getFunction() and not yield.isDelegating()
16+
|
17+
pred.asExpr() = yield.getOperand()
18+
) and
19+
succ = f.getReturnNode()
20+
)
21+
}
22+
23+
override predicate loadStoreStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
24+
exists(DataFlow::FunctionNode f | f.getFunction().isGenerator() |
25+
prop = iteratorElement() and
26+
exists(YieldExpr yield | yield.getContainer() = f.getFunction() and yield.isDelegating() |
1527
pred.asExpr() = yield.getOperand()
1628
) and
1729
succ = f.getReturnNode()

javascript/ql/test/library-tests/Generators/generators.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,24 @@
3030
} catch (e) {
3131
sink(e); // NOT OK
3232
}
33+
34+
function *delegating() {
35+
yield* delegate();
36+
}
37+
38+
function *delegate() {
39+
yield source;
40+
}
41+
42+
Array.from(delegating()).forEach(x => sink(x)); // NOT OK
43+
44+
function *delegating2() {
45+
yield* returnsTaint();
46+
}
47+
48+
function returnsTaint() {
49+
return source;
50+
}
51+
52+
Array.from(delegating2()).forEach(x => sink(x)); // OK
3353
});

0 commit comments

Comments
 (0)