mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
dataflow and typetracking steps for Maps and Sets
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
dataFlow
|
||||
| tst.js:2:16:2:23 | source() | tst.js:7:7:7:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:11:10:11:10 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:17:10:17:10 | v |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:21:10:21:14 | value |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:26:10:26:14 | value |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:30:7:30:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:34:7:34:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:38:7:38:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:42:7:42:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:46:7:46:7 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:50:10:50:10 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:53:8:53:21 | map.get("key") |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:55:8:55:28 | map.get ... nKey()) |
|
||||
typeTracking
|
||||
| tst.js:2:16:2:23 | source() | tst.js:2:16:2:23 | source() |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:6:14:6:14 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:10:15:10:15 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:16:15:16:15 | v |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:20:20:20:24 | value |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:25:14:25:18 | value |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:29:14:29:14 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:33:14:33:14 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:37:14:37:14 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:45:14:45:14 | e |
|
||||
| tst.js:2:16:2:23 | source() | tst.js:53:8:53:21 | map.get("key") |
|
||||
32
javascript/ql/test/library-tests/frameworks/Sets/test.ql
Normal file
32
javascript/ql/test/library-tests/frameworks/Sets/test.ql
Normal file
@@ -0,0 +1,32 @@
|
||||
import javascript
|
||||
private import semmle.javascript.dataflow.internal.StepSummary
|
||||
|
||||
class Config extends DataFlow::Configuration {
|
||||
Config() { this = "Config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source.(DataFlow::CallNode).getCalleeName() = "source" }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(DataFlow::CallNode call | call.getCalleeName() = "sink" | call.getAnArgument() = sink)
|
||||
}
|
||||
}
|
||||
|
||||
query predicate dataFlow(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
any(Config c).hasFlow(pred, succ)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode trackSource(DataFlow::TypeTracker t, DataFlow::SourceNode start) {
|
||||
t.start() and
|
||||
result.(DataFlow::CallNode).getCalleeName() = "source" and
|
||||
start = result
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | t = t2.step(trackSource(t2, start), result))
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = MapsAndSetsTypeTracking::mapOrSetStep(trackSource(t2, start), t, t2)
|
||||
)
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode typeTracking(DataFlow::Node start) {
|
||||
result = trackSource(DataFlow::TypeTracker::end(), start)
|
||||
}
|
||||
56
javascript/ql/test/library-tests/frameworks/Sets/tst.js
Normal file
56
javascript/ql/test/library-tests/frameworks/Sets/tst.js
Normal file
@@ -0,0 +1,56 @@
|
||||
(function() {
|
||||
var source = source();
|
||||
var set = new Set();
|
||||
set.add(source);
|
||||
|
||||
for (const e of set) {
|
||||
sink(e); // NOT OK.
|
||||
}
|
||||
|
||||
set.forEach(e => {
|
||||
sink(e);
|
||||
})
|
||||
|
||||
var map = new Map();
|
||||
map.set("key", source); map.set(unknownKey(), source);
|
||||
map.forEach(v => {
|
||||
sink(v);
|
||||
});
|
||||
|
||||
for (const [key, value] of map) {
|
||||
sink(value); // NOT OK.
|
||||
sink(key); // OK
|
||||
}
|
||||
|
||||
for (const value of map.values()) {
|
||||
sink(value); // NOT OK.
|
||||
}
|
||||
|
||||
for (const e of set.values()) {
|
||||
sink(e); // NOT OK
|
||||
}
|
||||
|
||||
for (const e of set.keys()) {
|
||||
sink(e); // NOT OK
|
||||
}
|
||||
|
||||
for (const e of new Set(set.keys())) {
|
||||
sink(e); // NOT OK
|
||||
}
|
||||
|
||||
for (const e of new Set([source])) {
|
||||
sink(e); // NOT OK (not caught by type-tracking, as it doesn't include array steps).
|
||||
}
|
||||
|
||||
for (const e of new Set(set)) {
|
||||
sink(e); // NOT OK
|
||||
}
|
||||
|
||||
for (const e of Array.from(set)) {
|
||||
sink(e); // NOT OK (not caught by type-tracking, as it doesn't include array steps).
|
||||
}
|
||||
|
||||
sink(map.get("key")); // NOT OK.
|
||||
sink(map.get("nonExistingKey")); // OK.
|
||||
sink(map.get(unknownKey())); // NOT OK (for data-flow). OK for type-tracking.
|
||||
})();
|
||||
Reference in New Issue
Block a user