Skip to content

Commit 49b1bfc

Browse files
committed
add a step for referencing instance/static methods on classes
1 parent 518bfa4 commit 49b1bfc

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,27 +54,34 @@ module CallGraph {
5454
PreCallGraphStep::step(any(DataFlow::Node n | function.flowsTo(n)), result)
5555
or
5656
imprecision = 0 and
57+
result = callgraphStep(function, t)
58+
}
59+
60+
/**
61+
* Gets a reference to `function` type-tracked by `t`.
62+
* Only considers callgraph specific steps.
63+
*/
64+
cached
65+
DataFlow::SourceNode callgraphStep(DataFlow::FunctionNode function, DataFlow::TypeTracker t) {
5766
exists(DataFlow::ClassNode cls |
5867
exists(string name |
5968
function = cls.getInstanceMethod(name) and
60-
cls.getAnInstanceMemberAccess(name, t.continue()).flowsTo(result)
69+
cls.getAnInstanceMemberAccess(name, t.continue()) = result
6170
or
6271
function = cls.getStaticMethod(name) and
63-
cls.getAClassReference(t.continue()).getAPropertyRead(name).flowsTo(result)
72+
cls.getAClassReference(t.continue()).getAPropertyRead(name) = result
6473
)
6574
or
6675
function = cls.getConstructor() and
67-
cls.getAClassReference(t.continue()).flowsTo(result)
76+
cls.getAClassReference(t.continue()) = result
6877
)
6978
or
70-
imprecision = 0 and
7179
exists(DataFlow::FunctionNode outer |
7280
result = getAFunctionReference(outer, 0, t.continue()).getAnInvocation() and
7381
locallyReturnedFunction(outer, function)
7482
)
7583
}
7684

77-
cached
7885
private predicate locallyReturnedFunction(
7986
DataFlow::FunctionNode outer, DataFlow::FunctionNode inner
8087
) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javascript
66
private import semmle.javascript.DynamicPropertyAccess
77
private import semmle.javascript.dataflow.internal.StepSummary
8+
private import semmle.javascript.dataflow.internal.CallGraphs
89

910
module HTTP {
1011
/**
@@ -299,6 +300,9 @@ module HTTP {
299300
exists(DataFlow::PartialInvokeNode call |
300301
succ = call.getBoundFunction(any(DataFlow::Node n | pred.flowsTo(n)), 0)
301302
)
303+
or
304+
// references to class methods
305+
succ = CallGraph::callgraphStep(pred, DataFlow::TypeTracker::end())
302306
}
303307

304308
/**

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ test_ResponseExpr
4343
| createServer.js:2:35:2:37 | res | createServer.js:2:20:2:41 | functio ... res) {} |
4444
| createServer.js:3:38:3:40 | res | createServer.js:3:23:3:44 | functio ... res) {} |
4545
| createServer.js:4:37:4:39 | res | createServer.js:4:31:4:46 | (req, res) => {} |
46+
| createServer.js:25:52:25:54 | res | createServer.js:25:37:27:5 | functio ... ;\\n } |
47+
| createServer.js:26:9:26:11 | res | createServer.js:25:37:27:5 | functio ... ;\\n } |
4648
| src/http.js:4:46:4:48 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
4749
| src/http.js:7:3:7:5 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
4850
| src/http.js:12:33:12:35 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} |
@@ -142,6 +144,8 @@ test_RouteHandler_getAResponseExpr
142144
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:35:2:37 | res |
143145
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res |
144146
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:37:4:39 | res |
147+
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:52:25:54 | res |
148+
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:26:9:26:11 | res |
145149
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:46:4:48 | res |
146150
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:7:3:7:5 | res |
147151
| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:33:12:35 | res |
@@ -180,6 +184,7 @@ test_ServerDefinition_getARouteHandler
180184
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
181185
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
182186
| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} |
187+
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } |
183188
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
184189
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
185190
| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} |
@@ -195,6 +200,7 @@ test_ServerDefinition_getARouteHandler
195200
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
196201
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
197202
test_ResponseSendArgument
203+
| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } |
198204
| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
199205
| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
200206
| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} |
@@ -210,6 +216,7 @@ test_RouteSetup_getARouteHandler
210216
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function |
211217
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest |
212218
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) |
219+
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } |
213220
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() |
214221
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
215222
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
@@ -258,6 +265,7 @@ test_RouteHandler
258265
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) |
259266
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) |
260267
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) |
268+
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) |
261269
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
262270
| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
263271
| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) |
@@ -276,6 +284,7 @@ test_RequestExpr
276284
| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} |
277285
| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} |
278286
| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} |
287+
| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } |
279288
| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
280289
| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
281290
| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
@@ -317,6 +326,7 @@ test_RouteHandler_getARequestExpr
317326
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req |
318327
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req |
319328
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req |
329+
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req |
320330
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req |
321331
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req |
322332
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req |

0 commit comments

Comments
 (0)