@@ -164,9 +164,9 @@ module Express {
164164 */
165165 DataFlow:: Node getRouteHandlerNode ( int index ) {
166166 // The first argument is a URI pattern if it is a string. If it could possibly be
167- // a function , we consider it to be a route handler, otherwise a URI pattern.
167+ // a non-string value , we consider it to be a route handler, otherwise a URI pattern.
168168 exists ( AnalyzedNode firstArg | firstArg = this .getArgument ( 0 ) .analyze ( ) |
169- if firstArg .getAType ( ) = TTFunction ( )
169+ if firstArg .getAType ( ) != TTString ( )
170170 then result = this .getArgument ( index )
171171 else (
172172 index >= 0 and result = this .getArgument ( index + 1 )
@@ -215,6 +215,10 @@ module Express {
215215 or
216216 Http:: routeHandlerStep ( result , succ ) and
217217 t = t2
218+ or
219+ DataFlow:: SharedFlowStep:: storeStep ( result .getALocalUse ( ) , succ ,
220+ DataFlow:: PseudoProperties:: arrayElement ( ) ) and
221+ t = t2 .continue ( )
218222 )
219223 }
220224
@@ -510,21 +514,6 @@ module Express {
510514 }
511515 }
512516
513- /**
514- * Holds if `call` is a chainable method call on the response object of `handler`.
515- */
516- private predicate isChainableResponseMethodCall (
517- RouteHandler handler , DataFlow:: MethodCallNode call
518- ) {
519- exists ( string name | call .calls ( handler .getAResponseNode ( ) , name ) |
520- name =
521- [
522- "append" , "attachment" , "location" , "send" , "sendStatus" , "set" , "status" , "type" , "vary" ,
523- "clearCookie" , "contentType" , "cookie" , "format" , "header" , "json" , "jsonp" , "links"
524- ]
525- )
526- }
527-
528517 /** An Express response source. */
529518 abstract class ResponseSource extends Http:: Servers:: ResponseSource { }
530519
@@ -535,11 +524,7 @@ module Express {
535524 private class ExplicitResponseSource extends ResponseSource {
536525 RouteHandler rh ;
537526
538- ExplicitResponseSource ( ) {
539- this = rh .getResponseParameter ( )
540- or
541- isChainableResponseMethodCall ( rh , this )
542- }
527+ ExplicitResponseSource ( ) { this = rh .getResponseParameter ( ) }
543528
544529 /**
545530 * Gets the route handler that provides this response.
@@ -556,6 +541,22 @@ module Express {
556541 override RouteHandler getRouteHandler ( ) { none ( ) } // Not known.
557542 }
558543
544+ private class ChainedResponse extends ResponseSource {
545+ private ResponseSource base ;
546+
547+ ChainedResponse ( ) {
548+ this =
549+ base .ref ( )
550+ .getAMethodCall ( [
551+ "append" , "attachment" , "location" , "send" , "sendStatus" , "set" , "status" , "type" ,
552+ "vary" , "clearCookie" , "contentType" , "cookie" , "format" , "header" , "json" , "jsonp" ,
553+ "links"
554+ ] )
555+ }
556+
557+ override Http:: RouteHandler getRouteHandler ( ) { result = base .getRouteHandler ( ) }
558+ }
559+
559560 /** An Express request source. */
560561 abstract class RequestSource extends Http:: Servers:: RequestSource { }
561562
@@ -777,12 +778,12 @@ module Express {
777778 /**
778779 * Holds if `e` is an HTTP request object.
779780 */
780- predicate isRequest ( DataFlow:: Node e ) { any ( RouteHandler rh ) . getARequestNode ( ) = e }
781+ predicate isRequest ( DataFlow:: Node e ) { any ( RequestSource src ) . ref ( ) . flowsTo ( e ) }
781782
782783 /**
783784 * Holds if `e` is an HTTP response object.
784785 */
785- predicate isResponse ( DataFlow:: Node e ) { any ( RouteHandler rh ) . getAResponseNode ( ) = e }
786+ predicate isResponse ( DataFlow:: Node e ) { any ( ResponseSource src ) . ref ( ) . flowsTo ( e ) }
786787
787788 /**
788789 * An access to the HTTP request body.
0 commit comments