@@ -81,11 +81,6 @@ abstract private class CollectionFlowStep extends DataFlow::AdditionalFlowStep {
8181 ) {
8282 this .loadStore ( pred , succ , loadProp , storeProp )
8383 }
84-
85- /**
86- * Holds if this step on a collection can load a value with a known key.
87- */
88- predicate canLoadValueWithKnownKey ( ) { none ( ) }
8984}
9085
9186/**
@@ -100,10 +95,7 @@ module CollectionsTypeTracking {
10095 exists ( CollectionFlowStep step , PseudoProperty field |
10196 summary = LoadStep ( field ) and
10297 step .load ( pred , result , field ) and
103- not (
104- step .canLoadValueWithKnownKey ( ) and // for a step that could load a known key,
105- field = mapValueUnknownKey ( ) // don't load values with an unknown key.
106- )
98+ not field = mapValueUnknownKey ( ) // prune unknown reads in type-tracking
10799 or
108100 summary = StoreStep ( field ) and
109101 step .store ( pred , result , field )
@@ -191,7 +183,7 @@ private module CollectionDataFlow {
191183 ) {
192184 pred = this and
193185 succ = element and
194- fromProp = mapValueUnknownKey ( ) and
186+ fromProp = mapValueAll ( ) and
195187 toProp = "1"
196188 }
197189 }
@@ -205,7 +197,7 @@ private module CollectionDataFlow {
205197 override predicate load ( DataFlow:: Node obj , DataFlow:: Node element , PseudoProperty prop ) {
206198 obj = this .getReceiver ( ) and
207199 element = this .getCallback ( 0 ) .getParameter ( 0 ) and
208- prop = [ setElement ( ) , mapValueUnknownKey ( ) ]
200+ prop = [ setElement ( ) , mapValueAll ( ) ]
209201 }
210202 }
211203
@@ -219,18 +211,18 @@ private module CollectionDataFlow {
219211 override predicate load ( DataFlow:: Node obj , DataFlow:: Node element , PseudoProperty prop ) {
220212 obj = this .getReceiver ( ) and
221213 element = this and
222- prop = mapValue ( this .getArgument ( 0 ) )
214+ // reading the join of known and unknown values
215+ ( prop = mapValue ( this .getArgument ( 0 ) ) or prop = mapValueUnknownKey ( ) )
223216 }
224-
225- override predicate canLoadValueWithKnownKey ( ) { any ( ) }
226217 }
227218
228219 /**
229220 * A call to the `set` method on a Map.
230221 *
231222 * If the key of the call to `set` has a known string value,
232223 * then the value will be saved into a pseudo-property corresponding to the known string value.
233- * The value will additionally be saved into a pseudo-property corresponding to values with unknown keys.
224+ * Otherwise the value will be saved into a pseudo-property corresponding to values with unknown keys.
225+ * The value will additionally be saved into a pseudo-property corresponding to all values.
234226 */
235227 class MapSet extends CollectionFlowStep , DataFlow:: MethodCallNode {
236228 MapSet ( ) { this .getMethodName ( ) = "set" }
@@ -246,9 +238,11 @@ private module CollectionDataFlow {
246238 * The pseudo-property represents both values where the key is a known string value (which is encoded in the pseudo-property),
247239 * and values where the key is unknown.
248240 *
241+ * Additionally, all elements are stored into the pseudo-property `mapValueAll()`.
242+ *
249243 * The return-type is `string` as this predicate is used to define which pseudo-properties exist.
250244 */
251- string getAPseudoProperty ( ) { result = [ mapValue ( this .getArgument ( 0 ) ) , mapValueUnknownKey ( ) ] }
245+ string getAPseudoProperty ( ) { result = [ mapValue ( this .getArgument ( 0 ) ) , mapValueAll ( ) ] }
252246 }
253247
254248 /**
@@ -262,7 +256,7 @@ private module CollectionDataFlow {
262256 ) {
263257 pred = this .getReceiver ( ) and
264258 succ = this and
265- fromProp = [ mapValueUnknownKey ( ) , setElement ( ) ] and
259+ fromProp = [ mapValueAll ( ) , setElement ( ) ] and
266260 toProp = iteratorElement ( )
267261 }
268262 }
0 commit comments