Skip to content

Commit 717ea23

Browse files
authored
Merge pull request #4311 from erik-krogh/indirect-fix
JS: improve join-order for HTTP::isDecoratedCall
2 parents 9a30686 + 32b0f1b commit 717ea23

File tree

1 file changed

+26
-4
lines changed
  • javascript/ql/src/semmle/javascript/frameworks

1 file changed

+26
-4
lines changed

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,39 @@ module HTTP {
237237
* Holds if `call` decorates the function `pred`.
238238
* This means that `call` returns a function that forwards its arguments to `pred`.
239239
* Only holds when the decorator looks like it is decorating a route-handler.
240+
*
241+
* Below is a code example relating `call`, `decoratee`, `outer`, `inner`.
242+
* ```
243+
* function outer(method) {
244+
* return function inner(req, res) {
245+
* return method.call(this, req, res);
246+
* };
247+
* }
248+
* var route = outer(function decoratee(req, res) { // <- call
249+
* res.end("foo");
250+
* });
251+
* ```
240252
*/
241253
private predicate isDecoratedCall(DataFlow::CallNode call, DataFlow::FunctionNode decoratee) {
242254
// indirect route-handler `result` is given to function `outer`, which returns function `inner` which calls the function `pred`.
243-
exists(int i, Function outer, Function inner |
255+
exists(int i, DataFlow::FunctionNode outer, HTTP::RouteHandlerCandidate inner |
244256
decoratee = call.getArgument(i).getALocalSource() and
245-
outer = call.getACallee() and
246-
inner = outer.getAReturnedExpr() and
247-
isAForwardingRouteHandlerCall(DataFlow::parameterNode(outer.getParameter(i)), inner.flow())
257+
outer.getFunction() = call.getACallee() and
258+
returnsRouteHandler(outer, inner) and
259+
isAForwardingRouteHandlerCall(outer.getParameter(i), inner)
248260
)
249261
}
250262

263+
/**
264+
* Holds if `fun` returns the route-handler-candidate `routeHandler`.
265+
*/
266+
pragma[noinline]
267+
private predicate returnsRouteHandler(
268+
DataFlow::FunctionNode fun, HTTP::RouteHandlerCandidate routeHandler
269+
) {
270+
routeHandler = fun.getAReturn().getALocalSource()
271+
}
272+
251273
/**
252274
* Holds if `f` looks like a route-handler and a call to `callee` inside `f` forwards all of the parameters from `f` to that call.
253275
*/

0 commit comments

Comments
 (0)