Skip to content

Commit 576e320

Browse files
committed
Python: sync
1 parent cbf1657 commit 576e320

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

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

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,47 @@ private module Cached {
1212
LevelStep() or
1313
CallStep() or
1414
ReturnStep() or
15-
StoreStep(TypeTrackerContent content) or
16-
LoadStep(TypeTrackerContent content) or
15+
StoreStep(TypeTrackerContentSet contents) or
16+
LoadStep(TypeTrackerContentSet contents) or
1717
JumpStep()
1818

19+
pragma[nomagic]
20+
private TypeTracker noContentTypeTracker(boolean hasCall) {
21+
result = MkTypeTracker(hasCall, noContent())
22+
}
23+
1924
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
2025
cached
2126
TypeTracker append(TypeTracker tt, StepSummary step) {
22-
exists(Boolean hasCall, OptionalTypeTrackerContent content |
23-
tt = MkTypeTracker(hasCall, content)
27+
exists(Boolean hasCall, OptionalTypeTrackerContent currentContent |
28+
tt = MkTypeTracker(hasCall, currentContent)
2429
|
2530
step = LevelStep() and result = tt
2631
or
27-
step = CallStep() and result = MkTypeTracker(true, content)
32+
step = CallStep() and result = MkTypeTracker(true, currentContent)
2833
or
2934
step = ReturnStep() and hasCall = false and result = tt
3035
or
31-
step = LoadStep(content) and result = MkTypeTracker(hasCall, noContent())
32-
or
33-
exists(TypeTrackerContent p |
34-
step = StoreStep(p) and content = noContent() and result = MkTypeTracker(hasCall, p)
35-
)
36-
or
3736
step = JumpStep() and
38-
result = MkTypeTracker(false, content)
37+
result = MkTypeTracker(false, currentContent)
38+
)
39+
or
40+
exists(TypeTrackerContentSet contents, boolean hasCall |
41+
step = LoadStep(pragma[only_bind_into](contents)) and
42+
tt = MkTypeTracker(hasCall, contents.getAReadContent()) and
43+
result = noContentTypeTracker(hasCall)
44+
or
45+
step = StoreStep(pragma[only_bind_into](contents)) and
46+
tt = noContentTypeTracker(hasCall) and
47+
result = MkTypeTracker(hasCall, contents.getAStoreContent())
3948
)
4049
}
4150

51+
pragma[nomagic]
52+
private TypeBackTracker noContentTypeBackTracker(boolean hasReturn) {
53+
result = MkTypeBackTracker(hasReturn, noContent())
54+
}
55+
4256
/** Gets the summary resulting from prepending `step` to this type-tracking summary. */
4357
cached
4458
TypeBackTracker prepend(TypeBackTracker tbt, StepSummary step) {
@@ -51,15 +65,19 @@ private module Cached {
5165
or
5266
step = ReturnStep() and result = MkTypeBackTracker(true, content)
5367
or
54-
exists(TypeTrackerContent p |
55-
step = LoadStep(p) and content = noContent() and result = MkTypeBackTracker(hasReturn, p)
56-
)
57-
or
58-
step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, noContent())
59-
or
6068
step = JumpStep() and
6169
result = MkTypeBackTracker(false, content)
6270
)
71+
or
72+
exists(TypeTrackerContentSet contents, boolean hasReturn |
73+
step = StoreStep(pragma[only_bind_into](contents)) and
74+
tbt = MkTypeBackTracker(hasReturn, contents.getAReadContent()) and
75+
result = noContentTypeBackTracker(hasReturn)
76+
or
77+
step = LoadStep(pragma[only_bind_into](contents)) and
78+
tbt = noContentTypeBackTracker(hasReturn) and
79+
result = MkTypeBackTracker(hasReturn, contents.getAStoreContent())
80+
)
6381
}
6482

6583
/**
@@ -99,9 +117,11 @@ class StepSummary extends TStepSummary {
99117
or
100118
this instanceof ReturnStep and result = "return"
101119
or
102-
exists(TypeTrackerContent content | this = StoreStep(content) | result = "store " + content)
120+
exists(TypeTrackerContentSet contents | this = StoreStep(contents) |
121+
result = "store " + contents
122+
)
103123
or
104-
exists(TypeTrackerContent content | this = LoadStep(content) | result = "load " + content)
124+
exists(TypeTrackerContentSet contents | this = LoadStep(contents) | result = "load " + contents)
105125
or
106126
this instanceof JumpStep and result = "jump"
107127
}
@@ -115,11 +135,11 @@ private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSu
115135
levelStep(nodeFrom, nodeTo) and
116136
summary = LevelStep()
117137
or
118-
exists(TypeTrackerContent content |
119-
StepSummary::localSourceStoreStep(nodeFrom, nodeTo, content) and
120-
summary = StoreStep(content)
138+
exists(TypeTrackerContentSet contents |
139+
StepSummary::localSourceStoreStep(nodeFrom, nodeTo, contents) and
140+
summary = StoreStep(contents)
121141
or
122-
basicLoadStep(nodeFrom, nodeTo, content) and summary = LoadStep(content)
142+
basicLoadStep(nodeFrom, nodeTo, contents) and summary = LoadStep(contents)
123143
)
124144
}
125145

@@ -189,8 +209,10 @@ module StepSummary {
189209
* function. This means we will track the fact that `x.attr` can have the type of `y` into the
190210
* assignment to `z` inside `bar`, even though this attribute write happens _after_ `bar` is called.
191211
*/
192-
predicate localSourceStoreStep(Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContent content) {
193-
exists(Node obj | nodeTo.flowsTo(obj) and basicStoreStep(nodeFrom, obj, content))
212+
predicate localSourceStoreStep(
213+
Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContentSet contents
214+
) {
215+
exists(Node obj | nodeTo.flowsTo(obj) and basicStoreStep(nodeFrom, obj, contents))
194216
}
195217
}
196218

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ class TypeTrackerContent extends OptionalTypeTrackerContent {
2828
/** The content string representing no value. */
2929
OptionalTypeTrackerContent noContent() { result = "" }
3030

31+
/** A content set, which is currently just a singleton set for Python. */
32+
class TypeTrackerContentSet extends TypeTrackerContent {
33+
/** Gets a content to read from at a load step. */
34+
TypeTrackerContent getAReadContent() { result = this }
35+
36+
/** Gets a content to write to at a store step. */
37+
TypeTrackerContent getAStoreContent() { result = this }
38+
}
39+
3140
predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStepForTypetracking/2;
3241

3342
predicate jumpStep = DataFlowPrivate::jumpStepSharedWithTypeTracker/2;

0 commit comments

Comments
 (0)