@@ -893,6 +893,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
893
893
or
894
894
result = this .asLambdaArgsNode ( ) .toString ( ) + " [LambdaArgs]"
895
895
or
896
+ result = this .asLambdaCaptureNode ( ) .toString ( ) + " [LambdaCapture]"
897
+ or
896
898
result = this .asLambdaInstancePostUpdateNode ( ) .toString ( ) + " [LambdaPostUpdate]"
897
899
or
898
900
exists ( DataFlowCall synthCall , ArgumentPosition apos , boolean isPost |
@@ -918,6 +920,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
918
920
919
921
Node asLambdaArgsNode ( ) { this = TNodeLambdaArgs ( result ) }
920
922
923
+ Node asLambdaCaptureNode ( ) { this = TNodeLambdaCapture ( result ) }
924
+
921
925
predicate isLambdaArgNode ( DataFlowCall synthCall , ArgumentPosition apos , boolean isPost ) {
922
926
this = TNodeLambdaArg ( synthCall , apos , isPost )
923
927
}
@@ -935,6 +939,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
935
939
or
936
940
this = TNodeLambdaArgs ( result )
937
941
or
942
+ this = TNodeLambdaCapture ( result )
943
+ or
944
+ this = TNodeLambdaCapture ( result )
945
+ or
938
946
exists ( DataFlowCall synthCall |
939
947
this = TNodeLambdaArg ( synthCall , _, _) and
940
948
lambdaCreation ( result , _, _, synthCall )
@@ -963,6 +971,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
963
971
or
964
972
nodeDataFlowType ( this .asLambdaArgsNode ( ) , result )
965
973
or
974
+ nodeDataFlowType ( this .asLambdaCaptureNode ( ) , result )
975
+ or
966
976
exists (
967
977
DataFlowCall synthCall , ArgumentPosition apos , DataFlowCallable c , ParameterNode p ,
968
978
ParameterPosition ppos
@@ -1112,7 +1122,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1112
1122
predicate clearsContentCached ( Node n , ContentSet c ) { clearsContent ( n , c ) }
1113
1123
1114
1124
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
+ }
1116
1131
1117
1132
cached
1118
1133
predicate isUnreachableInCallCached ( NodeRegion nr , DataFlowCall call ) {
@@ -1133,6 +1148,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1133
1148
exists ( n .asLambdaInstancePostUpdateNode ( ) ) or
1134
1149
exists ( n .asLambdaMallocNode ( ) ) or
1135
1150
exists ( n .asLambdaArgsNode ( ) ) or
1151
+ exists ( n .asLambdaCaptureNode ( ) ) or
1136
1152
n .isLambdaArgNode ( _, _, _) or
1137
1153
hiddenNode ( any ( NodeEx p | n .asParamReturnNode ( ) = p .asNode ( ) ) )
1138
1154
}
@@ -1554,7 +1570,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1554
1570
argumentValueFlowsThroughCand ( arg , node , false )
1555
1571
)
1556
1572
) and
1557
- not expectsContentCached ( node , _)
1573
+ not expectsContent ( node , _)
1558
1574
}
1559
1575
1560
1576
pragma [ nomagic]
@@ -2064,10 +2080,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2064
2080
lambdaCreation ( _, _, c , synthCall ) and
2065
2081
isParameterNode ( p , c , ppos ) and
2066
2082
parameterMatch ( ppos , apos ) and
2067
- not isLambdaInstanceParameter ( p ) and
2083
+ // not isLambdaInstanceParameter(p) and
2068
2084
exists ( ispost )
2069
2085
)
2070
- }
2086
+ } or
2087
+ TNodeLambdaCapture ( Node receiver ) { lambdaCall ( _, _, receiver ) }
2071
2088
2072
2089
/*
2073
2090
* foo(() => "taint"); // taint --store(ReturnValue)--> this (post-update) [ReturnValue]
@@ -2108,6 +2125,17 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2108
2125
or
2109
2126
LambdaFlow:: lambdaFlowsToPostUpdate ( node2 .asLambdaArgsNode ( ) , node1 .asNode ( ) ) and
2110
2127
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 = ""
2111
2139
}
2112
2140
2113
2141
cached
0 commit comments