Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e104b65

Browse files
committed
Python: sync TypeTracker.qll and adapt accordingly
fixup python
1 parent cd9cddf commit e104b65

3 files changed

Lines changed: 65 additions & 51 deletions

File tree

python/ql/lib/semmle/python/dataflow/new/TypeTracker.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
private import python
77
private import internal.TypeTracker as Internal
8+
private import internal.TypeTrackerSpecific as InternalSpecific
89

910
/** A string that may appear as the name of an attribute or access path. */
10-
class AttributeName = Internal::ContentName;
11+
class AttributeName = InternalSpecific::TypeTrackerContent;
1112

1213
/** An attribute name, or the empty string (representing no attribute). */
13-
class OptionalAttributeName = Internal::OptionalContentName;
14+
class OptionalAttributeName = InternalSpecific::OptionalTypeTrackerContent;
1415

1516
/**
1617
* The summary of the steps needed to track a value to a given dataflow node.

python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,6 @@
22

33
private 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-
265
cached
276
private 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
*/
241226
class 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
*/
391383
class 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

python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ class Node = DataFlowPublic::Node;
1111

1212
class TypeTrackingNode = DataFlowPublic::TypeTrackingNode;
1313

14+
/** A content name for use by type trackers, or the empty string. */
15+
class OptionalTypeTrackerContent extends string {
16+
OptionalTypeTrackerContent() {
17+
this = ""
18+
or
19+
this = getPossibleContentName()
20+
}
21+
}
22+
23+
/** A content name for use by type trackers. */
24+
class TypeTrackerContent extends OptionalTypeTrackerContent {
25+
TypeTrackerContent() { this != "" }
26+
}
27+
28+
/** The content string representing no value. */
29+
OptionalTypeTrackerContent noContent() { result = "" }
30+
1431
predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStepForTypetracking/2;
1532

1633
predicate jumpStep = DataFlowPrivate::jumpStepSharedWithTypeTracker/2;

0 commit comments

Comments
 (0)