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

Skip to content

Commit c97b9af

Browse files
committed
JS: Add SsaExplicitDefinition.getRhsNode
1 parent 8b60314 commit c97b9af

5 files changed

Lines changed: 95 additions & 0 deletions

File tree

javascript/ql/src/semmle/javascript/SSA.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,27 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
521521
) {
522522
getDef().getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
523523
}
524+
525+
/**
526+
* Gets the data flow node representing the incoming value assigned at this definition,
527+
* if any.
528+
*/
529+
DataFlow::Node getRhsNode() {
530+
exists(VarDef def | def = getDef() |
531+
result = def.getSource().flow()
532+
or
533+
exists(VarRef ref |
534+
ref = getSourceVariable().getAReference() and
535+
def.getTarget().(BindingPattern).getABindingVarRef() = ref and
536+
result = DataFlow::patternPropRead(ref)
537+
)
538+
or
539+
result = DataFlow::parameterNode(def)
540+
or
541+
// Handle class, function, namespace, and enum declaration statement
542+
result.getAstNode() = def.(Stmt)
543+
)
544+
}
524545
}
525546

526547
/**

javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,27 @@ module DataFlow {
10891089
nd = TExceptionalFunctionReturnNode(function)
10901090
}
10911091

1092+
/**
1093+
* INTERNAL. DO NOT USE.
1094+
*
1095+
* Gets the `PropRead` node corresponding to the value stored in the given
1096+
* binding pattern due to destructuring.
1097+
*
1098+
* For example, in `let { p: value } = f()`, the `value` pattern maps to a `PropRead`
1099+
* extracting the `p` property.
1100+
*/
1101+
DataFlow::PropRead patternPropRead(BindingPattern value) {
1102+
exists(PropertyPattern prop |
1103+
value = prop.getValuePattern() and
1104+
result = TPropNode(prop)
1105+
)
1106+
or
1107+
exists(ArrayPattern array |
1108+
value = array.getAnElement() and
1109+
result = TElementPatternNode(array, value)
1110+
)
1111+
}
1112+
10921113
/**
10931114
* A classification of flows that are not modeled, or only modeled incompletely, by
10941115
* `DataFlowNode`:
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
| tst.js:2:7:2:13 | a = g() | a | tst.js:2:11:2:13 | g() |
2+
| tst.js:4:7:4:24 | { propB: b } = g() | b | tst.js:4:9:4:16 | propB: b |
3+
| tst.js:6:7:6:34 | { propC ... } = g() | c | tst.js:6:9:6:16 | propC: c |
4+
| tst.js:6:7:6:34 | { propC ... } = g() | d | tst.js:6:19:6:26 | propD: d |
5+
| tst.js:8:7:8:41 | { array ... } = g() | elm1 | tst.js:8:22:8:25 | elm1 |
6+
| tst.js:8:7:8:41 | { array ... } = g() | elm2 | tst.js:8:28:8:31 | elm2 |
7+
| tst.js:17:3:17:22 | ({ propB: b }) = g() | b | tst.js:17:6:17:13 | propB: b |
8+
| tst.js:19:3:19:32 | ({ prop ... ) = g() | c | tst.js:19:6:19:13 | propC: c |
9+
| tst.js:19:3:19:32 | ({ prop ... ) = g() | d | tst.js:19:16:19:23 | propD: d |
10+
| tst.js:21:3:21:22 | [ elm1, elm2 ] = g() | elm1 | tst.js:21:5:21:8 | elm1 |
11+
| tst.js:21:3:21:22 | [ elm1, elm2 ] = g() | elm2 | tst.js:21:11:21:14 | elm2 |
12+
| tst.js:31:12:31:23 | [elm1, elm2] | elm1 | tst.js:31:13:31:16 | elm1 |
13+
| tst.js:31:12:31:23 | [elm1, elm2] | elm2 | tst.js:31:19:31:22 | elm2 |
14+
| tst.js:31:26:31:40 | { prop: value } | value | tst.js:31:28:31:38 | prop: value |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from SsaExplicitDefinition def
4+
select def, def.getSourceVariable(), def.getRhsNode()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function f() {
2+
let a = g();
3+
4+
let { propB: b } = g();
5+
6+
let { propC: c, propD: d } = g();
7+
8+
let { arrayProp: [ elm1, elm2 ] } = g();
9+
10+
a; // Ensure variables are live.
11+
b;
12+
c;
13+
d;
14+
elm1;
15+
elm2;
16+
17+
({ propB: b }) = g();
18+
19+
({ propC: c, propD: d }) = g();
20+
21+
[ elm1, elm2 ] = g();
22+
23+
a;
24+
b;
25+
c;
26+
d;
27+
elm1;
28+
elm2;
29+
}
30+
31+
function h([elm1, elm2], { prop: value }) {
32+
elm1;
33+
elm2;
34+
value;
35+
}

0 commit comments

Comments
 (0)