Skip to content

Commit 6333752

Browse files
authored
Python: Add getAMethodCall to LocalSourceNode
This seems like something we have been missing for a while now, so I figured it might be useful to add. It is roughly based on the JavaScript equivalent, with one major difference: in the JavaScript libraries, `getAMethodCall` is reserved for syntactic method calls (`obj.m(...)`) whereas `getAMemberInvocation` is used for both this and the case where the bound method `obj.m` is stored in a temporary variable and then subsequently invoked in the same local scope. It seems to me that the more general predicate is more useful, and hence should have the simpler name. (And also we don't really work with a notion of "invocation" in the Python libraries, so we would need a better name for it anyway.) I think as long as the documentation makes the behaviour clear, it should be okay.
1 parent e23b88b commit 6333752

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private class ClassDefinitionAsAttrWrite extends AttrWrite, CfgNode {
191191
* - Dynamic attribute reads using `getattr`: `getattr(object, attr)`
192192
* - Qualified imports: `from module import attr as name`
193193
*/
194-
abstract class AttrRead extends AttrRef, Node { }
194+
abstract class AttrRead extends AttrRef, Node, LocalSourceNode { }
195195

196196
/** A simple attribute read, e.g. `object.attr` */
197197
private class AttributeReadAsAttrRead extends AttrRead, CfgNode {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ class LocalSourceNode extends Node {
7878
*/
7979
CallCfgNode getACall() { Cached::call(this, result) }
8080

81+
/**
82+
* Gets a call to the method `methodName` on this node.
83+
*
84+
* Includes both calls that have the syntactic shape of a method call (as in `obj.m(...)`), and
85+
* calls where the callee undergoes some additional local data flow (as in `tmp = obj.m; m(...)`).
86+
*/
87+
CallCfgNode getAMethodCall(string methodName) {
88+
result = this.getAnAttributeRead(methodName).getACall()
89+
}
90+
8191
/**
8292
* Gets a node that this node may flow to using one heap and/or interprocedural step.
8393
*

0 commit comments

Comments
 (0)