Skip to content

Commit 9aa0cfb

Browse files
committed
Python: class callable -> class call
Only have one type of callable, but have an extra type of call. A constructor call directs to an init callable (should also handle `call` overrides at some point).
1 parent b2f1c43 commit 9aa0cfb

File tree

9 files changed

+370
-343
lines changed

9 files changed

+370
-343
lines changed

python/ql/src/experimental/dataflow/internal/DataFlowPrivate.qll

Lines changed: 35 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,6 @@ class ReadPreUpdateNode extends PreUpdateNode, CfgNode {
5050
override string label() { result = "read" }
5151
}
5252

53-
class MallocNode extends PreUpdateNode, ImplicitSelfArgumentNode {
54-
// ObjectCreationNode() { exists(ClassValue c | this.asCfgNode() = c.getACall()) }
55-
override string toString() {
56-
result = "malloc " + this.asCfgNode().(CallNode).getNode().(Call).toString()
57-
}
58-
59-
override string label() { result = "malloc" }
60-
}
61-
6253
/**
6354
* A node associated with an object after an operation that might have
6455
* changed its state.
@@ -191,67 +182,13 @@ private Node update(Node node) {
191182
// Global flow
192183
//--------
193184
/**
194-
* IPA type for DataFlowCallable.
195-
* A callable is either a callable value or a class.
185+
* A DataFlowCallable is any callable value.
196186
*/
197-
newtype TDataFlowCallable =
198-
TCallableValue(CallableValue callable) or
199-
TClassValue(ClassValue c)
200-
201-
/** Represents a callable */
202-
abstract class DataFlowCallable extends TDataFlowCallable {
203-
/** Gets a textual representation of this element. */
204-
abstract string toString();
205-
206-
/** Gets a call to this callable. */
207-
abstract CallNode getACall();
208-
209-
/** Gets the scope of this callable */
210-
abstract Scope getScope();
211-
212-
/** Gets the specified parameter of this callable */
213-
abstract NameNode getParameter(int n);
214-
215-
/** Gets the name of this callable. */
216-
abstract string getName();
217-
}
218-
219-
class DataFlowCallableValue extends DataFlowCallable, TCallableValue {
220-
CallableValue callable;
221-
222-
DataFlowCallableValue() { this = TCallableValue(callable) }
223-
224-
override string toString() { result = callable.toString() }
225-
226-
override CallNode getACall() { result = callable.getACall() }
227-
228-
override Scope getScope() { result = callable.getScope() }
229-
230-
override NameNode getParameter(int n) { result = callable.getParameter(n) }
231-
232-
override string getName() { result = callable.getName() }
233-
}
234-
235-
class DataFlowClassValue extends DataFlowCallable, TClassValue {
236-
ClassValue c;
237-
238-
DataFlowClassValue() { this = TClassValue(c) }
239-
240-
override string toString() { result = c.toString() }
241-
242-
override CallNode getACall() { result = c.getACall() }
243-
244-
override Scope getScope() { result = c.getScope() }
245-
246-
override NameNode getParameter(int n) {
247-
result.getNode() = c.getScope().getInitMethod().getArg(n + 1).asName()
248-
}
249-
250-
override string getName() { result = c.getName() }
251-
}
187+
class DataFlowCallable = CallableValue;
252188

253189
newtype TDataFlowCall =
254-
TCallNode(CallNode call) or
190+
TCallNode(CallNode call) { call = any(CallableValue c).getACall() } or
191+
TClassCall(CallNode call) { call = any(ClassValue c).getACall() } or
255192
TSpecialCall(SpecialMethodCallNode special)
256193

257194
abstract class DataFlowCall extends TDataFlowCall {
@@ -292,6 +229,36 @@ class CallNodeCall extends DataFlowCall, TCallNode {
292229
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getNode().getScope() }
293230
}
294231

232+
/** Represents a call to a class. */
233+
class ClassCall extends DataFlowCall, TClassCall {
234+
CallNode call;
235+
ClassValue c;
236+
237+
ClassCall() {
238+
this = TClassCall(call) and
239+
call = c.getACall()
240+
}
241+
242+
override string toString() { result = call.toString() }
243+
244+
override ControlFlowNode getArg(int n) {
245+
result = call.getArg(n - 1)
246+
or
247+
n = 0 and result = call
248+
}
249+
250+
override ControlFlowNode getNode() { result = call }
251+
252+
override DataFlowCallable getCallable() {
253+
exists(CallableValue callable |
254+
result = callable and
255+
c.getScope().getInitMethod() = callable.getScope()
256+
)
257+
}
258+
259+
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getNode().getScope() }
260+
}
261+
295262
/** Represents a call to a special method. */
296263
class SpecialCall extends DataFlowCall, TSpecialCall {
297264
SpecialMethodCallNode special;
@@ -304,9 +271,7 @@ class SpecialCall extends DataFlowCall, TSpecialCall {
304271

305272
override ControlFlowNode getNode() { result = special }
306273

307-
override DataFlowCallable getCallable() {
308-
result = TCallableValue(special.getResolvedSpecialMethod())
309-
}
274+
override DataFlowCallable getCallable() { result = special.getResolvedSpecialMethod() }
310275

311276
override DataFlowCallable getEnclosingCallable() {
312277
result.getScope() = special.getNode().getScope()
@@ -333,16 +298,6 @@ class ExplicitArgumentNode extends ArgumentNode {
333298
final override DataFlowCall getCall() { this.argumentOf(result, _) }
334299
}
335300

336-
class ImplicitSelfArgumentNode extends ArgumentNode {
337-
ImplicitSelfArgumentNode() { exists(ClassValue cv | node = cv.getACall()) }
338-
339-
/** Holds if this argument occurs at the given position in the given call. */
340-
override predicate argumentOf(DataFlowCall call, int pos) { call = TCallNode(node) and pos = -1 }
341-
342-
/** Gets the call in which this node is an argument. */
343-
final override DataFlowCall getCall() { result = TCallNode(node) }
344-
}
345-
346301
/** Gets a viable run-time target for the call `call`. */
347302
DataFlowCallable viableCallable(DataFlowCall call) { result = call.getCallable() }
348303

python/ql/test/experimental/dataflow/coverage/argumentRouting1.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ArgumentRoutingConfig extends DataFlow::Configuration {
1111
exists(AssignmentDefinition def, DataFlow::DataFlowCall call |
1212
def.getVariable() = node.(DataFlow::EssaNode).getVar() and
1313
def.getValue() = call.getNode() and
14-
call.getCallable().getName().matches("With\\_%")
14+
call.getNode().(CallNode).getNode().(Call).toString().matches("With\\_%") // TODO: Do not rely on toString
1515
) and
1616
node.(DataFlow::EssaNode).getVar().getName().matches("with\\_%")
1717
}

0 commit comments

Comments
 (0)