Skip to content

Commit 4cfbf15

Browse files
committed
deprecate RouteHandlerExpr and make RouteHandlerNode instead
1 parent 3da34ca commit 4cfbf15

9 files changed

+66
-24
lines changed

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

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ module Express {
298298
}
299299

300300
/**
301+
* DEPRECATED: Use `RouteHandlerNode` instead.
301302
* An expression used as an Express route handler, such as `submitHandler` below:
302303
* ```
303304
* app.post('/submit', submitHandler)
@@ -306,12 +307,56 @@ module Express {
306307
* Unlike `RouterHandler`, this is the argument passed to a setup, as opposed to
307308
* a function that flows into such an argument.
308309
*/
309-
class RouteHandlerExpr extends Expr {
310-
// TODO: DataFlow::Node
310+
deprecated class RouteHandlerExpr extends Expr {
311+
RouteHandlerNode node;
312+
313+
RouteHandlerExpr() { this.flow() = node }
314+
315+
/** Gets the setup call that registers this route handler. */
316+
deprecated RouteSetup getSetup() { result = node.getSetup() }
317+
318+
/** Gets the function body of this handler, if it is defined locally. */
319+
deprecated RouteHandler getBody() { result = node.getBody() }
320+
321+
/** Holds if this is not followed by more handlers. */
322+
deprecated predicate isLastHandler() { node.isLastHandler() }
323+
324+
/** Gets a route handler that immediately precedes this in the route stack. */
325+
deprecated Express::RouteHandlerExpr getPreviousMiddleware() {
326+
result = node.getPreviousMiddleware().asExpr()
327+
}
328+
329+
/** Gets a route handler that may follow immediately after this one in its route stack. */
330+
deprecated Express::RouteHandlerExpr getNextMiddleware() {
331+
result = node.getNextMiddleware().asExpr()
332+
}
333+
334+
/**
335+
* Gets a route handler that precedes this one (not necessarily immediately), may handle
336+
* same request method, and matches on the same path or a prefix.
337+
*/
338+
deprecated Express::RouteHandlerExpr getAMatchingAncestor() {
339+
result = node.getAMatchingAncestor().asExpr()
340+
}
341+
342+
/** Gets the router being registered as a sub-router here, if any. */
343+
deprecated RouterDefinition getAsSubRouter() { result = node.getAsSubRouter() }
344+
}
345+
346+
/**
347+
* An expression used as an Express route handler, such as `submitHandler` below:
348+
* ```
349+
* app.post('/submit', submitHandler)
350+
* ```
351+
*
352+
* Unlike `RouterHandler`, this is the argument passed to a setup, as opposed to
353+
* a function that flows into such an argument.
354+
*/
355+
class RouteHandlerNode extends DataFlow::Node {
311356
RouteSetup setup;
312357
int index;
313358

314-
RouteHandlerExpr() { this = setup.getRouteHandlerNode(index).asExpr() }
359+
RouteHandlerNode() { this = setup.getRouteHandlerNode(index) }
315360

316361
/**
317362
* Gets the setup call that registers this route handler.
@@ -322,7 +367,7 @@ module Express {
322367
* Gets the function body of this handler, if it is defined locally.
323368
*/
324369
RouteHandler getBody() {
325-
exists(DataFlow::SourceNode source | source = this.flow().getALocalSource() |
370+
exists(DataFlow::SourceNode source | source = this.getALocalSource() |
326371
result = source
327372
or
328373
DataFlow::functionOneWayForwardingStep(result.(DataFlow::SourceNode).getALocalUse(), source)
@@ -359,11 +404,11 @@ module Express {
359404
* In this case, the previous from `foo` is `auth` although they do not act on the
360405
* same requests.
361406
*/
362-
Express::RouteHandlerExpr getPreviousMiddleware() {
407+
Express::RouteHandlerNode getPreviousMiddleware() {
363408
index = 0 and
364409
result = setup.getRouter().getMiddlewareStackAt(setup.asExpr().getAPredecessor())
365410
or
366-
index > 0 and result = setup.getRouteHandlerNode(index - 1).asExpr()
411+
index > 0 and result = setup.getRouteHandlerNode(index - 1)
367412
or
368413
// Outside the router's original container, use the flow-insensitive model of its middleware stack.
369414
// Its state is not tracked to CFG nodes outside its original container.
@@ -377,7 +422,7 @@ module Express {
377422
/**
378423
* Gets a route handler that may follow immediately after this one in its route stack.
379424
*/
380-
Express::RouteHandlerExpr getNextMiddleware() { result.getPreviousMiddleware() = this }
425+
Express::RouteHandlerNode getNextMiddleware() { result.getPreviousMiddleware() = this }
381426

382427
/**
383428
* Gets a route handler that precedes this one (not necessarily immediately), may handle
@@ -390,7 +435,7 @@ module Express {
390435
* router installs a route handler `r1` on a path that matches the path of a route handler
391436
* `r2` installed on a subrouter, `r1` will not be recognized as an ancestor of `r2`.
392437
*/
393-
Express::RouteHandlerExpr getAMatchingAncestor() {
438+
Express::RouteHandlerNode getAMatchingAncestor() {
394439
result = this.getPreviousMiddleware+() and
395440
exists(RouteSetup resSetup | resSetup = result.getSetup() |
396441
// check whether request methods are compatible
@@ -407,7 +452,7 @@ module Express {
407452
or
408453
// if this is a sub-router, any previously installed middleware for the same
409454
// request method will necessarily match
410-
exists(RouteHandlerExpr outer |
455+
exists(RouteHandlerNode outer |
411456
setup.getRouter() = outer.getAsSubRouter() and
412457
outer.getSetup().handlesSameRequestMethodAs(setup) and
413458
result = outer.getAMatchingAncestor()
@@ -417,7 +462,7 @@ module Express {
417462
/**
418463
* Gets the router being registered as a sub-router here, if any.
419464
*/
420-
RouterDefinition getAsSubRouter() { isRouter(this.flow(), result) }
465+
RouterDefinition getAsSubRouter() { isRouter(this, result) }
421466
}
422467

423468
/**
@@ -934,22 +979,19 @@ module Express {
934979
*
935980
* If `node` is not in the same container where `router` was defined, the predicate has no result.
936981
*/
937-
Express::RouteHandlerExpr getMiddlewareStackAt(ControlFlowNode node) {
938-
// TODO: DataFlow::Node?
982+
Express::RouteHandlerNode getMiddlewareStackAt(ControlFlowNode node) {
939983
if
940984
exists(Express::RouteSetup setup | node = setup.asExpr() and setup.getRouter() = this |
941985
setup.isUseCall()
942986
)
943-
then
944-
result =
945-
node.(AST::ValueNode).flow().(Express::RouteSetup).getLastRouteHandlerNode().asExpr()
987+
then result = node.(AST::ValueNode).flow().(Express::RouteSetup).getLastRouteHandlerNode()
946988
else result = this.getMiddlewareStackAt(node.getAPredecessor())
947989
}
948990

949991
/**
950992
* Gets the final middleware registered on this router.
951993
*/
952-
Express::RouteHandlerExpr getMiddlewareStack() {
994+
Express::RouteHandlerNode getMiddlewareStack() {
953995
result = this.getMiddlewareStackAt(this.getContainer().getExit())
954996
}
955997
}

javascript/ql/test/library-tests/frameworks/Express/RouteHandlerExpr.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr(
4-
Express::RouteHandlerExpr rhe, Express::RouteSetup res0, boolean isLast
4+
Express::RouteHandlerNode rhe, Express::RouteSetup res0, boolean isLast
55
) {
66
(if rhe.isLastHandler() then isLast = true else isLast = false) and
77
res0 = rhe.getSetup()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr_getAMatchingAncestor(
4-
Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res
4+
Express::RouteHandlerNode expr, Express::RouteHandlerNode res
55
) {
66
res = expr.getAMatchingAncestor()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr_getAsSubRouter(
4-
Express::RouteHandlerExpr expr, Express::RouterDefinition res
4+
Express::RouteHandlerNode expr, Express::RouterDefinition res
55
) {
66
res = expr.getAsSubRouter()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr_getBody(
4-
Express::RouteHandlerExpr rhe, Express::RouteHandler res
4+
Express::RouteHandlerNode rhe, Express::RouteHandler res
55
) {
66
res = rhe.getBody()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr_getNextMiddleware(
4-
Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res
4+
Express::RouteHandlerNode expr, Express::RouteHandlerNode res
55
) {
66
res = expr.getNextMiddleware()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouteHandlerExpr_getPreviousMiddleware(
4-
Express::RouteHandlerExpr expr, Express::RouteHandlerExpr res
4+
Express::RouteHandlerNode expr, Express::RouteHandlerNode res
55
) {
66
res = expr.getPreviousMiddleware()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouterDefinition_getMiddlewareStack(
4-
Express::RouterDefinition r, Express::RouteHandlerExpr res
4+
Express::RouterDefinition r, Express::RouteHandlerNode res
55
) {
66
res = r.getMiddlewareStack()
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import javascript
22

33
query predicate test_RouterDefinition_getMiddlewareStackAt(
4-
Express::RouterDefinition r, ControlFlowNode nd, Express::RouteHandlerExpr res
4+
Express::RouterDefinition r, ControlFlowNode nd, Express::RouteHandlerNode res
55
) {
66
res = r.getMiddlewareStackAt(nd)
77
}

0 commit comments

Comments
 (0)