22
33private import TypeTrackerSpecific
44
5- /**
6- * A string that may appear as the name of a piece of content. This will usually include things like:
7- * - Attribute names (in Python)
8- * - Property names (in JavaScript)
9- *
10- * In general, this can also be used to model things like stores to specific list indices. To ensure
11- * correctness, it is important that
12- *
13- * - different types of content do not have overlapping names, and
14- * - the empty string `""` is not a valid piece of content, as it is used to indicate the absence of
15- * content instead.
16- */
17- class ContentName extends string {
18- ContentName ( ) { this = getPossibleContentName ( ) }
19- }
20-
21- /** A content name, or the empty string (representing no content). */
22- class OptionalContentName extends string {
23- OptionalContentName ( ) { this instanceof ContentName or this = "" }
24- }
25-
265cached
276private module Cached {
287 /**
@@ -33,23 +12,27 @@ private module Cached {
3312 LevelStep ( ) or
3413 CallStep ( ) or
3514 ReturnStep ( ) or
36- StoreStep ( ContentName content ) or
37- LoadStep ( ContentName content ) or
15+ StoreStep ( TypeTrackerContent content ) or
16+ LoadStep ( TypeTrackerContent content ) or
3817 JumpStep ( )
3918
4019 /** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
4120 cached
4221 TypeTracker append ( TypeTracker tt , StepSummary step ) {
43- exists ( Boolean hasCall , OptionalContentName content | tt = MkTypeTracker ( hasCall , content ) |
22+ exists ( Boolean hasCall , OptionalTypeTrackerContent content |
23+ tt = MkTypeTracker ( hasCall , content )
24+ |
4425 step = LevelStep ( ) and result = tt
4526 or
4627 step = CallStep ( ) and result = MkTypeTracker ( true , content )
4728 or
4829 step = ReturnStep ( ) and hasCall = false and result = tt
4930 or
50- step = LoadStep ( content ) and result = MkTypeTracker ( hasCall , "" )
31+ step = LoadStep ( content ) and result = MkTypeTracker ( hasCall , noContent ( ) )
5132 or
52- exists ( string p | step = StoreStep ( p ) and content = "" and result = MkTypeTracker ( hasCall , p ) )
33+ exists ( TypeTrackerContent p |
34+ step = StoreStep ( p ) and content = noContent ( ) and result = MkTypeTracker ( hasCall , p )
35+ )
5336 or
5437 step = JumpStep ( ) and
5538 result = MkTypeTracker ( false , content )
@@ -59,18 +42,20 @@ private module Cached {
5942 /** Gets the summary resulting from prepending `step` to this type-tracking summary. */
6043 cached
6144 TypeBackTracker prepend ( TypeBackTracker tbt , StepSummary step ) {
62- exists ( Boolean hasReturn , string content | tbt = MkTypeBackTracker ( hasReturn , content ) |
45+ exists ( Boolean hasReturn , OptionalTypeTrackerContent content |
46+ tbt = MkTypeBackTracker ( hasReturn , content )
47+ |
6348 step = LevelStep ( ) and result = tbt
6449 or
6550 step = CallStep ( ) and hasReturn = false and result = tbt
6651 or
6752 step = ReturnStep ( ) and result = MkTypeBackTracker ( true , content )
6853 or
69- exists ( string p |
70- step = LoadStep ( p ) and content = "" and result = MkTypeBackTracker ( hasReturn , p )
54+ exists ( TypeTrackerContent p |
55+ step = LoadStep ( p ) and content = noContent ( ) and result = MkTypeBackTracker ( hasReturn , p )
7156 )
7257 or
73- step = StoreStep ( content ) and result = MkTypeBackTracker ( hasReturn , "" )
58+ step = StoreStep ( content ) and result = MkTypeBackTracker ( hasReturn , noContent ( ) )
7459 or
7560 step = JumpStep ( ) and
7661 result = MkTypeBackTracker ( false , content )
@@ -114,9 +99,9 @@ class StepSummary extends TStepSummary {
11499 or
115100 this instanceof ReturnStep and result = "return"
116101 or
117- exists ( string content | this = StoreStep ( content ) | result = "store " + content )
102+ exists ( TypeTrackerContent content | this = StoreStep ( content ) | result = "store " + content )
118103 or
119- exists ( string content | this = LoadStep ( content ) | result = "load " + content )
104+ exists ( TypeTrackerContent content | this = LoadStep ( content ) | result = "load " + content )
120105 or
121106 this instanceof JumpStep and result = "jump"
122107 }
@@ -130,7 +115,7 @@ private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSu
130115 levelStep ( nodeFrom , nodeTo ) and
131116 summary = LevelStep ( )
132117 or
133- exists ( string content |
118+ exists ( TypeTrackerContent content |
134119 StepSummary:: localSourceStoreStep ( nodeFrom , nodeTo , content ) and
135120 summary = StoreStep ( content )
136121 or
@@ -204,12 +189,12 @@ module StepSummary {
204189 * function. This means we will track the fact that `x.attr` can have the type of `y` into the
205190 * assignment to `z` inside `bar`, even though this attribute write happens _after_ `bar` is called.
206191 */
207- predicate localSourceStoreStep ( Node nodeFrom , TypeTrackingNode nodeTo , string content ) {
192+ predicate localSourceStoreStep ( Node nodeFrom , TypeTrackingNode nodeTo , TypeTrackerContent content ) {
208193 exists ( Node obj | nodeTo .flowsTo ( obj ) and basicStoreStep ( nodeFrom , obj , content ) )
209194 }
210195}
211196
212- private newtype TTypeTracker = MkTypeTracker ( Boolean hasCall , OptionalContentName content )
197+ private newtype TTypeTracker = MkTypeTracker ( Boolean hasCall , OptionalTypeTrackerContent content )
213198
214199/**
215200 * A summary of the steps needed to track a value to a given dataflow node.
@@ -240,7 +225,7 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalContentNam
240225 */
241226class TypeTracker extends TTypeTracker {
242227 Boolean hasCall ;
243- OptionalContentName content ;
228+ OptionalTypeTrackerContent content ;
244229
245230 TypeTracker ( ) { this = MkTypeTracker ( hasCall , content ) }
246231
@@ -251,32 +236,38 @@ class TypeTracker extends TTypeTracker {
251236 string toString ( ) {
252237 exists ( string withCall , string withContent |
253238 ( if hasCall = true then withCall = "with" else withCall = "without" ) and
254- ( if content != "" then withContent = " with content " + content else withContent = "" ) and
239+ (
240+ if content != noContent ( )
241+ then withContent = " with content " + content
242+ else withContent = ""
243+ ) and
255244 result = "type tracker " + withCall + " call steps" + withContent
256245 )
257246 }
258247
259248 /**
260249 * Holds if this is the starting point of type tracking.
261250 */
262- predicate start ( ) { hasCall = false and content = "" }
251+ predicate start ( ) { hasCall = false and content = noContent ( ) }
263252
264253 /**
265254 * Holds if this is the starting point of type tracking, and the value starts in the content named `contentName`.
266255 * The type tracking only ends after the content has been loaded.
267256 */
268- predicate startInContent ( ContentName contentName ) { hasCall = false and content = contentName }
257+ predicate startInContent ( TypeTrackerContent contentName ) {
258+ hasCall = false and content = contentName
259+ }
269260
270261 /**
271262 * Holds if this is the starting point of type tracking
272263 * when tracking a parameter into a call, but not out of it.
273264 */
274- predicate call ( ) { hasCall = true and content = "" }
265+ predicate call ( ) { hasCall = true and content = noContent ( ) }
275266
276267 /**
277268 * Holds if this is the end point of type tracking.
278269 */
279- predicate end ( ) { content = "" }
270+ predicate end ( ) { content = noContent ( ) }
280271
281272 /**
282273 * INTERNAL. DO NOT USE.
@@ -290,15 +281,15 @@ class TypeTracker extends TTypeTracker {
290281 *
291282 * Gets the content associated with this type tracker.
292283 */
293- string getContent ( ) { result = content }
284+ OptionalTypeTrackerContent getContent ( ) { result = content }
294285
295286 /**
296287 * Gets a type tracker that starts where this one has left off to allow continued
297288 * tracking.
298289 *
299290 * This predicate is only defined if the type is not associated to a piece of content.
300291 */
301- TypeTracker continue ( ) { content = "" and result = this }
292+ TypeTracker continue ( ) { content = noContent ( ) and result = this }
302293
303294 /**
304295 * Gets the summary that corresponds to having taken a forwards
@@ -356,7 +347,8 @@ module TypeTracker {
356347 TypeTracker end ( ) { result .end ( ) }
357348}
358349
359- private newtype TTypeBackTracker = MkTypeBackTracker ( Boolean hasReturn , OptionalContentName content )
350+ private newtype TTypeBackTracker =
351+ MkTypeBackTracker ( Boolean hasReturn , OptionalTypeTrackerContent content )
360352
361353/**
362354 * A summary of the steps needed to back-track a use of a value to a given dataflow node.
@@ -390,7 +382,7 @@ private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, Optional
390382 */
391383class TypeBackTracker extends TTypeBackTracker {
392384 Boolean hasReturn ;
393- string content ;
385+ OptionalTypeTrackerContent content ;
394386
395387 TypeBackTracker ( ) { this = MkTypeBackTracker ( hasReturn , content ) }
396388
@@ -401,20 +393,24 @@ class TypeBackTracker extends TTypeBackTracker {
401393 string toString ( ) {
402394 exists ( string withReturn , string withContent |
403395 ( if hasReturn = true then withReturn = "with" else withReturn = "without" ) and
404- ( if content != "" then withContent = " with content " + content else withContent = "" ) and
396+ (
397+ if content != noContent ( )
398+ then withContent = " with content " + content
399+ else withContent = ""
400+ ) and
405401 result = "type back-tracker " + withReturn + " return steps" + withContent
406402 )
407403 }
408404
409405 /**
410406 * Holds if this is the starting point of type tracking.
411407 */
412- predicate start ( ) { hasReturn = false and content = "" }
408+ predicate start ( ) { hasReturn = false and content = noContent ( ) }
413409
414410 /**
415411 * Holds if this is the end point of type tracking.
416412 */
417- predicate end ( ) { content = "" }
413+ predicate end ( ) { content = noContent ( ) }
418414
419415 /**
420416 * INTERNAL. DO NOT USE.
@@ -429,7 +425,7 @@ class TypeBackTracker extends TTypeBackTracker {
429425 *
430426 * This predicate is only defined if the type has not been tracked into a piece of content.
431427 */
432- TypeBackTracker continue ( ) { content = "" and result = this }
428+ TypeBackTracker continue ( ) { content = noContent ( ) and result = this }
433429
434430 /**
435431 * Gets the summary that corresponds to having taken a backwards
0 commit comments