Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a5c9492

Browse files
committed
add support for fromJS in the Immutable model
1 parent 6cbe4ca commit a5c9492

3 files changed

Lines changed: 19 additions & 17 deletions

File tree

javascript/ql/src/semmle/javascript/frameworks/Immutable.qll

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,26 @@ private module Immutable {
2929
}
3030

3131
/**
32-
* An instance of an immutable map.
32+
* An instance of any immutable collection.
3333
*/
34-
API::Node immutableMap() {
35-
result = immutableImport().getMember("Map").getReturn()
34+
API::Node immutableCollection() {
35+
result = immutableImport().getMember(["Map", "fromJS"]).getReturn()
3636
or
37-
result = immutableMap().getMember("set").getReturn()
37+
result.getAnImmediateUse() = step(immutableCollection().getAUse())
3838
}
3939

40-
/**
41-
* An instance of any immutable collection.
42-
*/
43-
API::Node immutableCollection() { result = immutableMap() }
44-
4540
/**
4641
* Gets the immutable collection where `pred` has been stored using the name `prop`.
4742
*/
4843
DataFlow::SourceNode storeStep(DataFlow::Node pred, string prop) {
49-
exists(DataFlow::CallNode call | call = immutableImport().getMember("Map").getACall() |
44+
exists(DataFlow::CallNode call |
45+
call = immutableImport().getMember(["Map", "fromJS"]).getACall()
46+
|
5047
pred = call.getOptionArgument(0, prop) and
5148
result = call
5249
)
5350
or
54-
exists(DataFlow::CallNode call | call = immutableMap().getMember("set").getACall() |
51+
exists(DataFlow::CallNode call | call = immutableCollection().getMember("set").getACall() |
5552
call.getArgument(0).mayHaveStringValue(prop) and
5653
pred = call.getArgument(1) and
5754
result = call
@@ -63,7 +60,9 @@ private module Immutable {
6360
*/
6461
DataFlow::Node loadStep(DataFlow::Node pred, string prop) {
6562
// map.get()
66-
exists(DataFlow::MethodCallNode call | call = immutableMap().getMember("get").getACall() |
63+
exists(DataFlow::MethodCallNode call |
64+
call = immutableCollection().getMember("get").getACall()
65+
|
6766
call.getArgument(0).mayHaveStringValue(prop) and
6867
pred = call.getReceiver() and
6968
result = call
@@ -73,14 +72,14 @@ private module Immutable {
7372
/**
7473
* Gets an immutable collection that contains all the elements from `pred`.
7574
*/
76-
DataFlow::Node step(DataFlow::Node pred) {
75+
DataFlow::SourceNode step(DataFlow::Node pred) {
7776
// map.set() copies all existing values
78-
exists(DataFlow::CallNode call | call = immutableMap().getMember("set").getACall() |
77+
exists(DataFlow::CallNode call | call = immutableCollection().getMember("set").getACall() |
7978
pred = call.getReceiver() and
8079
result = call
8180
)
8281
or
83-
// toJS() or any immutable collection converts it to a plain JavaScript object/array.
82+
// toJS() or any immutable collection converts it to a plain JavaScript object/array (and vice versa for `fromJS`).
8483
exists(DataFlow::CallNode call | call = immutableCollection().getMember("toJS").getACall() |
8584
pred = call.getReceiver() and
8685
result = call

javascript/ql/test/library-tests/frameworks/Immutable/immutable.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var obj = { a: source("a"), b: source("b1") };
22
sink(obj["a"]); // NOT OK
33

4-
const { Map } = require('immutable');
4+
const { Map, fromJS } = require('immutable');
55

66
const map1 = Map(obj);
77

@@ -17,4 +17,6 @@ sink(map1.get("d")); // OK
1717
sink(map3.get("d")); // NOT OK
1818

1919

20-
sink(map3.toJS()["a"]); // NOT OK
20+
sink(map3.toJS()["a"]); // NOT OK
21+
22+
sink(fromJS({"e": source("e")}).get("e")); // NOT OK

javascript/ql/test/library-tests/frameworks/Immutable/tests.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
| immutable.js:1:32:1:43 | source("b1") | immutable.js:8:6:8:18 | map1.get("b") |
66
| immutable.js:1:32:1:43 | source("b1") | immutable.js:13:6:13:18 | map2.get("b") |
77
| immutable.js:15:28:15:38 | source("d") | immutable.js:17:6:17:18 | map3.get("d") |
8+
| immutable.js:22:19:22:29 | source("e") | immutable.js:22:6:22:40 | fromJS( ... et("e") |

0 commit comments

Comments
 (0)