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

Skip to content

Commit fc8caa6

Browse files
committed
Python: Prepare for general content in type-tracker
Due to the char-pred of Content, this change should keep exactly the same behavior as before.
1 parent dacf7d7 commit fc8caa6

2 files changed

Lines changed: 21 additions & 38 deletions

File tree

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
private import internal.TypeTrackingImpl as Impl
77
import Impl::Shared::TypeTracking<Impl::TypeTrackingInput>
8+
private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic
89

910
/** A string that may appear as the name of an attribute or access path. */
1011
class AttributeName = Impl::TypeTrackingInput::Content;
@@ -40,17 +41,20 @@ class TypeTracker extends Impl::TypeTracker {
4041
* Holds if this is the starting point of type tracking, and the value starts in the attribute named `attrName`.
4142
* The type tracking only ends after the attribute has been loaded.
4243
*/
43-
predicate startInAttr(string attrName) { this.startInContent(attrName) }
44+
predicate startInAttr(string attrName) {
45+
exists(DataFlowPublic::AttributeContent content | content.getAttribute() = attrName |
46+
this.startInContent(content)
47+
)
48+
}
4449

4550
/**
4651
* INTERNAL. DO NOT USE.
4752
*
4853
* Gets the attribute associated with this type tracker.
4954
*/
5055
string getAttr() {
51-
result = this.getContent().asSome()
52-
or
53-
this.getContent().isNone() and
54-
result = ""
56+
if this.getContent().asSome() instanceof DataFlowPublic::AttributeContent
57+
then result = this.getContent().asSome().(DataFlowPublic::AttributeContent).getAttribute()
58+
else result = ""
5559
}
5660
}

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

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,14 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input {
9797

9898
private module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>;
9999

100-
/**
101-
* Gets the name of a possible piece of content. For Python, this is currently only attribute names,
102-
* using the name of the attribute for the corresponding content.
103-
*/
104-
private string getPossibleContentName() {
105-
Stages::TypeTracking::ref() and // the TypeTracking::append() etc. predicates that we want to cache depend on this predicate, so we can place the `ref()` call here to get around identical files.
106-
result = any(DataFlowPublic::AttrRef a).getAttributeName()
107-
}
108-
109100
module TypeTrackingInput implements Shared::TypeTrackingInput {
110101
class Node = DataFlowPublic::Node;
111102

112103
class LocalSourceNode = DataFlowPublic::LocalSourceNode;
113104

114-
class Content instanceof string {
115-
Content() { this = getPossibleContentName() }
116-
117-
string toString() { result = this }
105+
class Content extends DataFlowPublic::Content {
106+
// this char-pred is just a temporary restriction while transitioning to more general content
107+
Content() { this instanceof DataFlowPublic::AttributeContent }
118108
}
119109

120110
/**
@@ -181,46 +171,35 @@ module TypeTrackingInput implements Shared::TypeTrackingInput {
181171
* Holds if `nodeFrom` is being written to the `content` content of the object in `nodeTo`.
182172
*/
183173
predicate storeStep(Node nodeFrom, Node nodeTo, Content content) {
184-
exists(DataFlowPublic::AttrWrite a |
185-
a.mayHaveAttributeName(content) and
174+
exists(DataFlowPublic::AttrWrite a, string attrName |
175+
content.(DataFlowPublic::AttributeContent).getAttribute() = attrName and
176+
a.mayHaveAttributeName(attrName) and
186177
nodeFrom = a.getValue() and
187178
nodeTo = a.getObject()
188179
)
189180
or
190-
exists(DataFlowPublic::ContentSet contents |
191-
contents.(DataFlowPublic::AttributeContent).getAttribute() = content
192-
|
193-
TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, contents)
194-
)
181+
TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, content)
195182
}
196183

197184
/**
198185
* Holds if `nodeTo` is the result of accessing the `content` content of `nodeFrom`.
199186
*/
200187
predicate loadStep(Node nodeFrom, LocalSourceNode nodeTo, Content content) {
201-
exists(DataFlowPublic::AttrRead a |
202-
a.mayHaveAttributeName(content) and
188+
exists(DataFlowPublic::AttrRead a, string attrName |
189+
content.(DataFlowPublic::AttributeContent).getAttribute() = attrName and
190+
a.mayHaveAttributeName(attrName) and
203191
nodeFrom = a.getObject() and
204192
nodeTo = a
205193
)
206194
or
207-
exists(DataFlowPublic::ContentSet contents |
208-
contents.(DataFlowPublic::AttributeContent).getAttribute() = content
209-
|
210-
TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, contents)
211-
)
195+
TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, content)
212196
}
213197

214198
/**
215199
* Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`.
216200
*/
217201
predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content loadContent, Content storeContent) {
218-
exists(DataFlowPublic::ContentSet loadContents, DataFlowPublic::ContentSet storeContents |
219-
loadContents.(DataFlowPublic::AttributeContent).getAttribute() = loadContent and
220-
storeContents.(DataFlowPublic::AttributeContent).getAttribute() = storeContent
221-
|
222-
TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContents, storeContents)
223-
)
202+
TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent)
224203
}
225204

226205
/**

0 commit comments

Comments
 (0)