@@ -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