Skip to content

Commit 3cc9313

Browse files
committed
JS: Add test for selector nodes with multiple access paths
1 parent 4a11ae9 commit 3cc9313

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

javascript/ql/lib/semmle/javascript/frameworks/Redux.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,4 +1231,9 @@ module Redux {
12311231
}
12321232
}
12331233
}
1234+
1235+
/** For testing only. */
1236+
module Internal {
1237+
predicate getRootStateAccessPath = rootStateAccessPath/1;
1238+
}
12341239
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useSelector } from 'react-redux';
2+
3+
function useSelectorWrapped(fn) {
4+
return useSelector(fn);
5+
}
6+
7+
function MyComponent(props) {
8+
const x1 = useSelectorWrapped(state => state.x1);
9+
const x2 = useSelectorWrapped(state => state.x2);
10+
const x3 = useSelectorWrapped(state => state.x3);
11+
const x4 = useSelectorWrapped(state => state.x4);
12+
const x5 = useSelectorWrapped(state => state.x5);
13+
14+
return <span>X</span>;
15+
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,16 @@ taintFlow
113113
| react-redux.jsx:69:31:69:38 | source() | react-redux.jsx:76:10:76:36 | props.p ... Action3 |
114114
| react-redux.jsx:70:30:70:37 | source() | react-redux.jsx:77:10:77:28 | props.propFromAsync |
115115
reactComponentRef
116+
| accessPaths.js:7:1:15:1 | functio ... pan>;\\n} | accessPaths.js:7:1:15:1 | functio ... pan>;\\n} |
116117
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} |
117118
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:94:28:94:84 | connect ... ponent) |
118119
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:97:12:97:12 | c |
120+
ambiguousAccessPath
121+
| accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() | x1 |
122+
| accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() | x2 |
123+
| accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() | x3 |
124+
| accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() | x4 |
125+
| accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() | x5 |
119126
getAffectedStateAccessPath
120127
| react-redux.jsx:12:33:17:9 | (state, ... } | toolkit |
121128
| react-redux.jsx:18:41:23:9 | (state, ... } | toolkit |
@@ -163,3 +170,24 @@ reducerToStateStep
163170
| react-redux.jsx:35:45:35:58 | action.payload | react-redux.jsx:86:31:86:54 | state.m ... alValue |
164171
| react-redux.jsx:39:42:39:55 | action.payload | react-redux.jsx:87:32:87:56 | state.m ... lValue2 |
165172
| react-redux.jsx:44:27:46:14 | [1, 2, ... }) | react-redux.jsx:88:32:88:56 | state.m ... lValue3 |
173+
getRootStateAccessPath
174+
| manual | react-redux.jsx:86:31:86:42 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
175+
| manual | react-redux.jsx:87:32:87:43 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
176+
| manual | react-redux.jsx:88:32:88:43 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
177+
| manual.manualValue | react-redux.jsx:86:31:86:54 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue") |
178+
| manual.manualValue2 | react-redux.jsx:87:32:87:56 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue2") |
179+
| manual.manualValue3 | react-redux.jsx:88:32:88:56 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue3") |
180+
| toolkit | react-redux.jsx:84:32:84:44 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit") |
181+
| toolkit | react-redux.jsx:85:24:85:36 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit") |
182+
| toolkit.asyncValue | react-redux.jsx:85:24:85:47 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit").getMember("asyncValue") |
183+
| toolkit.value | react-redux.jsx:84:32:84:50 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit").getMember("value") |
184+
| x1 | accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() |
185+
| x1 | accessPaths.js:8:44:8:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x1") |
186+
| x2 | accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() |
187+
| x2 | accessPaths.js:9:44:9:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x2") |
188+
| x3 | accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() |
189+
| x3 | accessPaths.js:10:44:10:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x3") |
190+
| x4 | accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() |
191+
| x4 | accessPaths.js:11:44:11:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x4") |
192+
| x5 | accessPaths.js:4:12:4:26 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getReturn() |
193+
| x5 | accessPaths.js:12:44:12:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x5") |

javascript/ql/test/library-tests/frameworks/Redux/test.ql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,10 @@ query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
6363
query DataFlow::SourceNode reactComponentRef(ReactComponent component) {
6464
result = component.getAComponentCreatorReference()
6565
}
66+
67+
query predicate ambiguousAccessPath(API::Node node, string path) {
68+
count(string accessPath | Redux::Internal::getRootStateAccessPath(accessPath) = node) > 1 and
69+
Redux::Internal::getRootStateAccessPath(path) = node
70+
}
71+
72+
query predicate getRootStateAccessPath = Redux::Internal::getRootStateAccessPath/1;

0 commit comments

Comments
 (0)