Skip to content

Commit 9e097f5

Browse files
committed
Python: Improve PoorMansFunctionResolution
1 parent 0d4cb1e commit 9e097f5

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

python/ql/lib/semmle/python/frameworks/internal/PoorMansFunctionResolution.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,28 @@ private DataFlow::TypeTrackingNode poorMansFunctionTracker(DataFlow::TypeTracker
8080
* inst = MyClass()
8181
* print(inst.my_method)
8282
* ```
83+
*
84+
* But is able to handle simple method calls within a class, but does not take MRO into
85+
* account.
86+
* ```py
87+
* class MyClass:
88+
* def method1(self);
89+
* pass
90+
*
91+
* def method2(self);
92+
* self.method1()
93+
* ```
8394
*/
8495
DataFlow::Node poorMansFunctionTracker(Function func) {
8596
poorMansFunctionTracker(DataFlow::TypeTracker::end(), func).flowsTo(result)
97+
or
98+
// simple method calls within a class
99+
// TODO: Should take MRO into account
100+
exists(Class cls, Function otherFunc, DataFlow::Node selfRef |
101+
cls.getAMethod() = func and
102+
cls.getAMethod() = otherFunc
103+
|
104+
selfRef.getALocalSource().(DataFlow::ParameterNode).getParameter() = otherFunc.getArg(0) and
105+
result.(DataFlow::AttrRead).accesses(selfRef, func.getName())
106+
)
86107
}

python/ql/test/library-tests/frameworks/internal-ql-helpers/test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def static():
2323

2424
def method2(self):
2525
print("method2", self)
26-
self.method1()
26+
self.method1() # $ resolved=method1
2727
self.base_method()
28-
self.cls_method()
29-
self.static()
28+
self.cls_method() # $ resolved=cls_method
29+
self.static() # $ resolved=static
3030

3131

3232

python/ql/test/library-tests/frameworks/stdlib/wsgiref_simple_server_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ def __init__(self):
3131
super().__init__(ADDRESS, wsgiref.simple_server.WSGIRequestHandler)
3232
self.set_app(self.my_method)
3333

34-
def my_method(self, _env, start_response): # $ MISSING: requestHandler
34+
def my_method(self, _env, start_response): # $ requestHandler
3535
start_response("200 OK", [])
36-
return [b"my_method"] # $ MISSING: HttpResponse responseBody=List
36+
return [b"my_method"] # $ HttpResponse responseBody=List
3737

3838

3939
case = sys.argv[1]

0 commit comments

Comments
 (0)