Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,16 @@ module DataFlow {
)
}

/**
* Holds if there is a step from `pred` to `succ` through a field accessed through `this` in a class.
*/
predicate localFieldStep(DataFlow::Node pred, DataFlow::Node succ) {
exists (ClassNode cls, string prop |
pred = cls.getAReceiverNode().getAPropertyWrite(prop).getRhs() and
succ = cls.getAReceiverNode().getAPropertyRead(prop)
)
}

/**
* Gets the data flow node representing the source of definition `def`, taking
* flow through IIFE calls into account.
Expand Down
9 changes: 9 additions & 0 deletions javascript/ql/src/semmle/javascript/dataflow/Nodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,15 @@ class ClassNode extends DataFlow::SourceNode {
.(AbstractCallable)
.getFunction()
}

/**
* Gets the receiver of an instance member or constructor of this class.
*/
DataFlow::SourceNode getAReceiverNode() {
result = getConstructor().getReceiver()
or
result = getAnInstanceMember().getReceiver()
}
}

module ClassNode {
Expand Down
3 changes: 3 additions & 0 deletions javascript/ql/test/library-tests/ClassNode/FieldStep.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| tst2.js:3:14:3:14 | x | tst2.js:7:5:7:10 | this.x |
| tst2.js:3:14:3:14 | x | tst2.js:8:25:8:30 | this.x |
| tst2.js:3:14:3:14 | x | tst2.js:12:12:12:17 | this.x |
5 changes: 5 additions & 0 deletions javascript/ql/test/library-tests/ClassNode/FieldStep.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import javascript

from DataFlow::Node pred, DataFlow::Node succ
where DataFlow::localFieldStep(pred, succ)
select pred, succ
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
| namespace.js:5:32:5:44 | function() {} | Baz.method | method |
| tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C.method | method |
| tst2.js:11:13:13:3 | () {\\n ... .x;\\n } | C.getter | getter |
| tst.js:4:17:4:21 | () {} | A.instanceMethod | method |
| tst.js:7:6:7:10 | () {} | A.bar | method |
| tst.js:9:10:9:14 | () {} | A.baz | getter |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
| namespace.js:5:32:5:44 | function() {} | Baz.method |
| tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C.method |
| tst.js:4:17:4:21 | () {} | A.instanceMethod |
| tst.js:7:6:7:10 | () {} | A.bar |
| tst.js:17:19:17:31 | function() {} | B.foo |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:3:15:3:14 | this |
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:5:32:5:31 | this |
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:2:14:2:13 | this |
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:6:9:6:8 | this |
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:11:13:11:12 | this |
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:3:9:3:8 | this |
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:4:17:4:16 | this |
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:7:6:7:5 | this |
| tst.js:3:1:10:1 | class A ... () {}\\n} | tst.js:9:10:9:9 | this |
| tst.js:13:1:13:21 | class A ... ds A {} | tst.js:13:20:13:19 | this |
| tst.js:15:1:15:15 | function B() {} | tst.js:15:1:15:0 | this |
| tst.js:15:1:15:15 | function B() {} | tst.js:17:19:17:18 | this |
| tst.js:19:1:19:15 | function C() {} | tst.js:19:1:19:0 | this |
| tst.js:19:1:19:15 | function C() {} | tst.js:21:19:21:18 | this |
| tst.js:23:1:23:15 | function D() {} | tst.js:23:1:23:0 | this |
| tst.js:23:1:23:15 | function D() {} | tst.js:25:13:25:12 | this |
| tst.js:23:1:23:15 | function D() {} | tst.js:26:13:26:12 | this |
| tst.js:23:1:23:15 | function D() {} | tst.js:27:4:27:3 | this |
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import javascript

from DataFlow::ClassNode cls
select cls, cls.getAReceiverNode()
14 changes: 14 additions & 0 deletions javascript/ql/test/library-tests/ClassNode/tst2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class C {
constructor(x) {
this.x = x;
}

method() {
this.x;
let closure = () => this.x;
}

get getter() {
return this.x;
}
}