add of Set, Stack and similar to the Immutable model

This commit is contained in:
Erik Krogh Kristensen
2021-02-04 12:05:04 +01:00
parent b74df66463
commit 6cbf7b3267
3 changed files with 40 additions and 4 deletions

View File

@@ -38,10 +38,18 @@ private module Immutable {
API::Node immutableCollection() {
// keep this predicate in sync with the constructors defined in `storeStep`/`step`.
result =
immutableImport().getMember(["Map", "OrderedMap", "List", "fromJS", "merge"]).getReturn()
immutableImport()
.getMember(["Map", "OrderedMap", "List", "Stack", "Set", "OrderedSet", "fromJS", "merge"])
.getReturn()
or
result = immutableImport().getMember("Record").getReturn().getReturn()
or
result =
immutableImport()
.getMember(["List", "Set", "OrderedSet", "Stack"])
.getMember("of")
.getReturn()
or
result = immutableCollection().getMember(["set", "map", "filter", "push", "merge"]).getReturn()
}
@@ -59,7 +67,7 @@ private module Immutable {
or
// Immutable.List()
exists(DataFlow::CallNode call, DataFlow::ArrayCreationNode arr |
call = immutableImport().getMember("List").getACall()
call = immutableImport().getMember(["List", "Stack", "Set", "OrderedSet"]).getACall()
|
arr = call.getArgument(0).getALocalSource() and
exists(int i |
@@ -91,6 +99,19 @@ private module Immutable {
pred = [factoryCall, recordCall].getOptionArgument(0, prop) and
result = recordCall
)
or
// List/Set/Stack.of(values)
exists(API::CallNode call |
call =
immutableImport()
.getMember(["List", "Set", "OrderedSet", "Stack"])
.getMember("of")
.getACall()
|
pred = call.getAnArgument() and
result = call and
prop = DataFlow::PseudoProperties::arrayElement()
)
}
/**

View File

@@ -1,7 +1,7 @@
var obj = { a: source("a"), b: source("b1") };
sink(obj["a"]); // NOT OK
const { Map, fromJS, List, OrderedMap, Record, merge } = require('immutable');
const { Map, fromJS, List, OrderedMap, Record, merge, Stack, Set, OrderedSet } = require('immutable');
const map1 = Map(obj);
@@ -45,4 +45,14 @@ const map6 = merge(Map({}), Record({a: source()})());
sink(map6.get("a")); // NOT OK
const map7 = map6.merge(Map({b: source()}));
sink(map7.get("b")); // NOT OK
sink(map7.get("b")); // NOT OK
Stack.of(source(), "foobar").forEach(x => sink(x)); // NOT OK
List.of(source()).filter(x => true).toList().forEach(x => sink(x)); // NOT OK
Set.of(source()).filter(x => true).toList().forEach(x => sink(x)); // NOT OK
Set([source()]).filter(x => true).toList().forEach(x => sink(x)); // NOT OK
OrderedSet([source()]).filter(x => true).toList().forEach(x => sink(x)); // NOT OK

View File

@@ -15,3 +15,8 @@
| immutable.js:39:58:39:65 | source() | immutable.js:41:6:41:18 | map5.get("b") |
| immutable.js:44:40:44:47 | source() | immutable.js:45:6:45:18 | map6.get("a") |
| immutable.js:47:33:47:40 | source() | immutable.js:48:6:48:18 | map7.get("b") |
| immutable.js:50:10:50:17 | source() | immutable.js:50:48:50:48 | x |
| immutable.js:52:9:52:16 | source() | immutable.js:52:64:52:64 | x |
| immutable.js:54:8:54:15 | source() | immutable.js:54:63:54:63 | x |
| immutable.js:56:6:56:13 | source() | immutable.js:56:62:56:62 | x |
| immutable.js:58:13:58:20 | source() | immutable.js:58:69:58:69 | x |