Skip to content

Commit 7faa4fd

Browse files
author
Max Schaefer
committed
JavaScript: Add test case exposing two bugs in data flow library.
This test case exposes two bugs in our data flow library (fixed by the two previous commits): - the charpreds of `SourcePathNode` and `SinkPathNode` only ensured that they were on a path from a source to a sink, not that they actually were the source/sink themselves; - function summarization would allow for non-level paths; in the test case, this meant that one of the summaries for `source` represented the path returning from `source` on line 13 and then flowing back into the call on line 15, in the process transforming the parity of the flow label and hence causing a spurious flow.
1 parent 465be47 commit 7faa4fd

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| tst5.mjs:13:12:13:20 | source(0) | tst5.mjs:18:6:18:9 | flow |
2+
| tst5.mjs:15:8:15:19 | source(flow) | tst5.mjs:16:13:16:16 | flow |
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import javascript
2+
3+
class Parity extends DataFlow::FlowLabel {
4+
Parity() { this = "even" or this = "odd" }
5+
6+
Parity flip() { result != this }
7+
}
8+
9+
class Config extends DataFlow::Configuration {
10+
Config() { this = "config" }
11+
12+
override predicate isSource(DataFlow::Node nd, DataFlow::FlowLabel lbl) {
13+
nd.(DataFlow::CallNode).getCalleeName() = "source" and
14+
lbl = "even"
15+
}
16+
17+
override predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) {
18+
nd = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getAnArgument() and
19+
lbl = "even"
20+
}
21+
22+
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predLabel, DataFlow::FlowLabel succLabel) {
23+
exists(DataFlow::CallNode c | c = succ |
24+
c.getCalleeName() = "inc" and
25+
pred = c.getAnArgument() and
26+
succLabel = predLabel.(Parity).flip()
27+
)
28+
}
29+
}
30+
31+
from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
32+
where cfg.hasFlowPath(source, sink)
33+
select source, sink
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function source(x) {
2+
return x;
3+
}
4+
5+
function sink(x) {
6+
return x;
7+
}
8+
9+
function inc(x) {
10+
return x+1;
11+
}
12+
13+
var flow = source(0); // source
14+
flow = inc(flow);
15+
flow = source(flow); // source
16+
flow = sink(flow); // sink for line 15, but not for line 13 (wrong parity)
17+
flow = inc(flow);
18+
sink(flow); // sink for line 13, but not for line 15 (wrong parity)

0 commit comments

Comments
 (0)