Skip to content

Commit 9c93ad9

Browse files
committed
Python: sync
1 parent dd23e12 commit 9c93ad9

File tree

2 files changed

+37
-39
lines changed

2 files changed

+37
-39
lines changed

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

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

1919
pragma[nomagic]
@@ -24,27 +24,30 @@ private module Cached {
2424
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
2525
cached
2626
TypeTracker append(TypeTracker tt, StepSummary step) {
27-
exists(Boolean hasCall, OptionalTypeTrackerContent currentContent |
28-
tt = MkTypeTracker(hasCall, currentContent)
27+
exists(Boolean hasCall, OptionalTypeTrackerContent currentContents |
28+
tt = MkTypeTracker(hasCall, currentContents)
2929
|
3030
step = LevelStep() and result = tt
3131
or
32-
step = CallStep() and result = MkTypeTracker(true, currentContent)
32+
step = CallStep() and result = MkTypeTracker(true, currentContents)
3333
or
3434
step = ReturnStep() and hasCall = false and result = tt
3535
or
3636
step = JumpStep() and
37-
result = MkTypeTracker(false, currentContent)
37+
result = MkTypeTracker(false, currentContents)
3838
)
3939
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)
40+
exists(TypeTrackerContent storeContents, boolean hasCall |
41+
exists(TypeTrackerContent loadContents |
42+
step = LoadStep(pragma[only_bind_into](loadContents)) and
43+
tt = MkTypeTracker(hasCall, storeContents) and
44+
compatibleContents(storeContents, loadContents) and
45+
result = noContentTypeTracker(hasCall)
46+
)
4447
or
45-
step = StoreStep(pragma[only_bind_into](contents)) and
48+
step = StoreStep(pragma[only_bind_into](storeContents)) and
4649
tt = noContentTypeTracker(hasCall) and
47-
result = MkTypeTracker(hasCall, contents.getAStoreContent())
50+
result = MkTypeTracker(hasCall, storeContents)
4851
)
4952
}
5053

@@ -69,14 +72,17 @@ private module Cached {
6972
result = MkTypeBackTracker(false, content)
7073
)
7174
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)
75+
exists(TypeTrackerContent loadContents, boolean hasReturn |
76+
exists(TypeTrackerContent storeContents |
77+
step = StoreStep(pragma[only_bind_into](storeContents)) and
78+
tbt = MkTypeBackTracker(hasReturn, loadContents) and
79+
compatibleContents(storeContents, loadContents) and
80+
result = noContentTypeBackTracker(hasReturn)
81+
)
7682
or
77-
step = LoadStep(pragma[only_bind_into](contents)) and
83+
step = LoadStep(pragma[only_bind_into](loadContents)) and
7884
tbt = noContentTypeBackTracker(hasReturn) and
79-
result = MkTypeBackTracker(hasReturn, contents.getAStoreContent())
85+
result = MkTypeBackTracker(hasReturn, loadContents)
8086
)
8187
}
8288

@@ -117,11 +123,9 @@ class StepSummary extends TStepSummary {
117123
or
118124
this instanceof ReturnStep and result = "return"
119125
or
120-
exists(TypeTrackerContentSet contents | this = StoreStep(contents) |
121-
result = "store " + contents
122-
)
126+
exists(TypeTrackerContent content | this = StoreStep(content) | result = "store " + content)
123127
or
124-
exists(TypeTrackerContentSet contents | this = LoadStep(contents) | result = "load " + contents)
128+
exists(TypeTrackerContent content | this = LoadStep(content) | result = "load " + content)
125129
or
126130
this instanceof JumpStep and result = "jump"
127131
}
@@ -135,11 +139,11 @@ private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSu
135139
levelStep(nodeFrom, nodeTo) and
136140
summary = LevelStep()
137141
or
138-
exists(TypeTrackerContentSet contents |
139-
StepSummary::localSourceStoreStep(nodeFrom, nodeTo, contents) and
140-
summary = StoreStep(contents)
142+
exists(TypeTrackerContent content |
143+
StepSummary::localSourceStoreStep(nodeFrom, nodeTo, content) and
144+
summary = StoreStep(content)
141145
or
142-
basicLoadStep(nodeFrom, nodeTo, contents) and summary = LoadStep(contents)
146+
basicLoadStep(nodeFrom, nodeTo, content) and summary = LoadStep(content)
143147
)
144148
}
145149

@@ -185,7 +189,7 @@ module StepSummary {
185189
}
186190

187191
/**
188-
* Holds if `nodeFrom` is being written to the `contents` of the object in `nodeTo`.
192+
* Holds if `nodeFrom` is being written to the `content` of the object in `nodeTo`.
189193
*
190194
* Note that `nodeTo` will always be a local source node that flows to the place where the content
191195
* is written in `basicStoreStep`. This may lead to the flow of information going "back in time"
@@ -204,15 +208,13 @@ module StepSummary {
204208
* def bar(x):
205209
* z = x.attr
206210
* ```
207-
* for the attribute write `x.attr = y`, we will have `contents` being the literal string `"attr"`,
211+
* for the attribute write `x.attr = y`, we will have `content` being the literal string `"attr"`,
208212
* `nodeFrom` will be `y`, and `nodeTo` will be the object `Foo()` created on the first line of the
209213
* function. This means we will track the fact that `x.attr` can have the type of `y` into the
210214
* assignment to `z` inside `bar`, even though this attribute write happens _after_ `bar` is called.
211215
*/
212-
predicate localSourceStoreStep(
213-
Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContentSet contents
214-
) {
215-
exists(Node obj | nodeTo.flowsTo(obj) and basicStoreStep(nodeFrom, obj, contents))
216+
predicate localSourceStoreStep(Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContent content) {
217+
exists(Node obj | nodeTo.flowsTo(obj) and basicStoreStep(nodeFrom, obj, content))
216218
}
217219
}
218220

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,9 @@ class TypeTrackerContent extends OptionalTypeTrackerContent {
2828
/** Gets 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 }
31+
pragma[inline]
32+
predicate compatibleContents(TypeTrackerContent storeContent, TypeTrackerContent loadContent) {
33+
storeContent = loadContent
3834
}
3935

4036
predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStepForTypetracking/2;

0 commit comments

Comments
 (0)