Skip to content

Commit 08f480a

Browse files
authored
Merge pull request github#6351 from tausbn/python-hotfix-localsourcenode-typetrackingnode
Python: Hotfix `LocalSourceNode`
2 parents 7fdac2a + 020c6e3 commit 08f480a

File tree

2 files changed

+54
-45
lines changed

2 files changed

+54
-45
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
lgtm,codescanning
2-
* The `track` and `backtrack` methods on `LocalSourceNode` have been deprecated. When writing
3-
type trackers, the corresponding methods on `TypeTrackingNode` should be used instead.
2+
* The `track` and `backtrack` methods on `LocalSourceNode` are in the process of being deprecated. When using type trackers, the corresponding methods on `TypeTrackingNode` should be used instead.

python/ql/src/semmle/python/dataflow/new/internal/LocalSources.qll

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -104,67 +104,67 @@ class LocalSourceNode extends Node {
104104
}
105105

106106
/**
107-
* DEPRECATED. Use `TypeTrackingNode::track` instead.
108-
*
109107
* Gets a node that this node may flow to using one heap and/or interprocedural step.
110108
*
111109
* See `TypeTracker` for more details about how to use this.
112110
*/
113111
pragma[inline]
114-
deprecated LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
112+
LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
115113

116114
/**
117-
* DEPRECATED. Use `TypeTrackingNode::backtrack` instead.
118-
*
119115
* Gets a node that may flow into this one using one heap and/or interprocedural step.
120116
*
121117
* See `TypeBackTracker` for more details about how to use this.
122118
*/
123119
pragma[inline]
124-
deprecated LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) {
125-
t2 = t.step(result, this)
126-
}
120+
LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
127121
}
128122

129123
/**
130124
* A node that can be used for type tracking or type back-tracking.
131125
*
132126
* All steps made during type tracking should be between instances of this class.
133127
*/
134-
class TypeTrackingNode extends Node {
135-
TypeTrackingNode() {
136-
this instanceof LocalSourceNode
137-
or
138-
this instanceof ModuleVariableNode
128+
class TypeTrackingNode = LocalSourceNode;
129+
130+
/** Temporary holding ground for the `TypeTrackingNode` class. */
131+
private module FutureWork {
132+
class FutureTypeTrackingNode extends Node {
133+
FutureTypeTrackingNode() {
134+
this instanceof LocalSourceNode
135+
or
136+
this instanceof ModuleVariableNode
137+
}
138+
139+
/**
140+
* Holds if this node can flow to `nodeTo` in one or more local flow steps.
141+
*
142+
* For `ModuleVariableNode`s, the only "local" step is to the node itself.
143+
* For `LocalSourceNode`s, this is the usual notion of local flow.
144+
*/
145+
pragma[inline]
146+
predicate flowsTo(Node node) {
147+
this instanceof ModuleVariableNode and this = node
148+
or
149+
this.(LocalSourceNode).flowsTo(node)
150+
}
151+
152+
/**
153+
* Gets a node that this node may flow to using one heap and/or interprocedural step.
154+
*
155+
* See `TypeTracker` for more details about how to use this.
156+
*/
157+
pragma[inline]
158+
TypeTrackingNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
159+
160+
/**
161+
* Gets a node that may flow into this one using one heap and/or interprocedural step.
162+
*
163+
* See `TypeBackTracker` for more details about how to use this.
164+
*/
165+
pragma[inline]
166+
TypeTrackingNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
139167
}
140-
141-
/**
142-
* Holds if this node can flow to `nodeTo` in one or more local flow steps.
143-
*
144-
* For `ModuleVariableNode`s, the only "local" step is to the node itself.
145-
* For `LocalSourceNode`s, this is the usual notion of local flow.
146-
*/
147-
predicate flowsTo(Node node) {
148-
this instanceof ModuleVariableNode and this = node
149-
or
150-
this.(LocalSourceNode).flowsTo(node)
151-
}
152-
153-
/**
154-
* Gets a node that this node may flow to using one heap and/or interprocedural step.
155-
*
156-
* See `TypeTracker` for more details about how to use this.
157-
*/
158-
pragma[inline]
159-
TypeTrackingNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
160-
161-
/**
162-
* Gets a node that may flow into this one using one heap and/or interprocedural step.
163-
*
164-
* See `TypeBackTracker` for more details about how to use this.
165-
*/
166-
pragma[inline]
167-
TypeTrackingNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
168168
}
169169

170170
cached
@@ -179,11 +179,21 @@ private module Cached {
179179
source = sink
180180
or
181181
exists(Node second |
182-
simpleLocalFlowStep(source, second) and
183-
simpleLocalFlowStep*(second, sink)
182+
localSourceFlowStep(source, second) and
183+
localSourceFlowStep*(second, sink)
184184
)
185185
}
186186

187+
/**
188+
* Helper predicate for `hasLocalSource`. Removes any steps go to module variable reads, as these
189+
* are already local source nodes in their own right.
190+
*/
191+
cached
192+
private predicate localSourceFlowStep(Node nodeFrom, Node nodeTo) {
193+
simpleLocalFlowStep(nodeFrom, nodeTo) and
194+
not nodeTo = any(ModuleVariableNode v).getARead()
195+
}
196+
187197
/**
188198
* Holds if `base` flows to the base of `ref` and `ref` has attribute name `attr`.
189199
*/

0 commit comments

Comments
 (0)