@@ -893,6 +893,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
893893 or
894894 result = this .asLambdaArgsNode ( ) .toString ( ) + " [LambdaArgs]"
895895 or
896+ result = this .asLambdaCaptureNode ( ) .toString ( ) + " [LambdaCapture]"
897+ or
896898 result = this .asLambdaInstancePostUpdateNode ( ) .toString ( ) + " [LambdaPostUpdate]"
897899 or
898900 exists ( DataFlowCall synthCall , ArgumentPosition apos , boolean isPost |
@@ -918,6 +920,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
918920
919921 Node asLambdaArgsNode ( ) { this = TNodeLambdaArgs ( result ) }
920922
923+ Node asLambdaCaptureNode ( ) { this = TNodeLambdaCapture ( result ) }
924+
921925 predicate isLambdaArgNode ( DataFlowCall synthCall , ArgumentPosition apos , boolean isPost ) {
922926 this = TNodeLambdaArg ( synthCall , apos , isPost )
923927 }
@@ -935,6 +939,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
935939 or
936940 this = TNodeLambdaArgs ( result )
937941 or
942+ this = TNodeLambdaCapture ( result )
943+ or
944+ this = TNodeLambdaCapture ( result )
945+ or
938946 exists ( DataFlowCall synthCall |
939947 this = TNodeLambdaArg ( synthCall , _, _) and
940948 lambdaCreation ( result , _, _, synthCall )
@@ -963,6 +971,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
963971 or
964972 nodeDataFlowType ( this .asLambdaArgsNode ( ) , result )
965973 or
974+ nodeDataFlowType ( this .asLambdaCaptureNode ( ) , result )
975+ or
966976 exists (
967977 DataFlowCall synthCall , ArgumentPosition apos , DataFlowCallable c , ParameterNode p ,
968978 ParameterPosition ppos
@@ -1112,7 +1122,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
11121122 predicate clearsContentCached ( Node n , ContentSet c ) { clearsContent ( n , c ) }
11131123
11141124 cached
1115- predicate expectsContentCached ( Node n , ContentSet c ) { expectsContent ( n , c ) }
1125+ predicate expectsContentCached ( NodeEx n , ContentSet c ) {
1126+ expectsContent ( n .asNode ( ) , c )
1127+ or
1128+ exists ( n .asLambdaCaptureNode ( ) ) and
1129+ isVariableCaptureContentSet ( c )
1130+ }
11161131
11171132 cached
11181133 predicate isUnreachableInCallCached ( NodeRegion nr , DataFlowCall call ) {
@@ -1133,6 +1148,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
11331148 exists ( n .asLambdaInstancePostUpdateNode ( ) ) or
11341149 exists ( n .asLambdaMallocNode ( ) ) or
11351150 exists ( n .asLambdaArgsNode ( ) ) or
1151+ exists ( n .asLambdaCaptureNode ( ) ) or
11361152 n .isLambdaArgNode ( _, _, _) or
11371153 hiddenNode ( any ( NodeEx p | n .asParamReturnNode ( ) = p .asNode ( ) ) )
11381154 }
@@ -1554,7 +1570,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
15541570 argumentValueFlowsThroughCand ( arg , node , false )
15551571 )
15561572 ) and
1557- not expectsContentCached ( node , _)
1573+ not expectsContent ( node , _)
15581574 }
15591575
15601576 pragma [ nomagic]
@@ -2064,10 +2080,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
20642080 lambdaCreation ( _, _, c , synthCall ) and
20652081 isParameterNode ( p , c , ppos ) and
20662082 parameterMatch ( ppos , apos ) and
2067- not isLambdaInstanceParameter ( p ) and
2083+ // not isLambdaInstanceParameter(p) and
20682084 exists ( ispost )
20692085 )
2070- }
2086+ } or
2087+ TNodeLambdaCapture ( Node receiver ) { lambdaCall ( _, _, receiver ) }
20712088
20722089 /*
20732090 * foo(() => "taint"); // taint --store(ReturnValue)--> this (post-update) [ReturnValue]
@@ -2108,6 +2125,17 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
21082125 or
21092126 LambdaFlow:: lambdaFlowsToPostUpdate ( node2 .asLambdaArgsNode ( ) , node1 .asNode ( ) ) and
21102127 model = ""
2128+ or
2129+ // When data is stored in a captured variable content and reaches a lambda call,
2130+ // we need it to propagate back out to the lambda. We do this by adding flow
2131+ // from the lambda receiver to the post-update of the lambda receiver, but _only_
2132+ // for captured variable content. The latter restriction is enforced by going via
2133+ // an intermediate `expectsContent` node.
2134+ node1 .asNode ( ) = node2 .asLambdaCaptureNode ( ) and
2135+ model = ""
2136+ or
2137+ node2 .asNode ( ) .( PostUpdateNode ) .getPreUpdateNode ( ) = node1 .asLambdaCaptureNode ( ) and
2138+ model = ""
21112139 }
21122140
21132141 cached
0 commit comments