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

Skip to content

Commit 9d40a6c

Browse files
committed
Python points-to: restore getArgumentForCall() API method.
1 parent 90bbfd3 commit 9d40a6c

5 files changed

Lines changed: 53 additions & 11 deletions

File tree

python/ql/src/semmle/python/objects/Callables.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ abstract class CallableObjectInternal extends ObjectInternal {
5353
override int length() { none() }
5454

5555
abstract predicate neverReturns();
56+
5657
}
5758

5859

@@ -151,6 +152,11 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
151152
override predicate neverReturns() {
152153
InterProceduralPointsTo::neverReturns(this.getScope())
153154
}
155+
156+
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
157+
function = this and offset = 0
158+
}
159+
154160
}
155161

156162

@@ -262,6 +268,10 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
262268
this = Module::named("sys").attr("exit")
263269
}
264270

271+
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
272+
function = this and offset = 0
273+
}
274+
265275
}
266276

267277

@@ -347,6 +357,10 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
347357

348358
override predicate neverReturns() { none() }
349359

360+
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
361+
function = this and offset = 0
362+
}
363+
350364
}
351365

352366
class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
@@ -422,6 +436,10 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
422436
this.getFunction().neverReturns()
423437
}
424438

439+
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
440+
function = this.getFunction() and offset = 1
441+
}
442+
425443
}
426444

427445

python/ql/src/semmle/python/objects/Classes.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject
122122

123123
override boolean isComparable() { result = true }
124124

125+
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
126+
this.lookup("__init__", function, _) and offset = 1
127+
}
128+
125129
}
126130

127131
class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObject {

python/ql/src/semmle/python/objects/ObjectAPI.qll

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,35 @@ class CallableValue extends Value {
118118
result = this.(CallableObjectInternal).getParameterByName(name)
119119
}
120120

121-
ControlFlowNode getArgumentForCall(CallNode call, NameNode param) {
122-
this.getACall() = call and
123-
(
124-
exists(int n | call.getArg(n) = result and param = this.getParameter(n))
121+
ControlFlowNode getArgumentForCall(CallNode call, int n) {
122+
exists(ObjectInternal called, int offset |
123+
PointsToInternal::pointsTo(call.getFunction(), _, called, _) and
124+
called.functionAndOffset(this, offset)
125+
|
126+
call.getArg(n-offset) = result
125127
or
126-
exists(string name | call.getArgByName(name) = result and param = this.getParameterByName(name))
128+
exists(string name | call.getArgByName(name) = result and this.(PythonFunctionObjectInternal).getScope().getArg(n+offset).getName() = name)
129+
or
130+
called instanceof BoundMethodObjectInternal and
131+
offset = 1 and n = 0 and result = call.getFunction().(AttrNode).getObject()
127132
)
128-
or
129-
exists(BoundMethodObjectInternal bm |
130-
result = getArgumentForCall(call, param) and
131-
this = bm.getFunction()
133+
}
134+
135+
ControlFlowNode getNamedArgumentForCall(CallNode call, string name) {
136+
exists(CallableObjectInternal called, int offset |
137+
PointsToInternal::pointsTo(call.getFunction(), _, called, _) and
138+
called.functionAndOffset(this, offset)
139+
|
140+
exists(int n |
141+
call.getArg(n) = result and
142+
this.(PythonFunctionObjectInternal).getScope().getArg(n+offset).getName() = name
143+
)
144+
or
145+
call.getArgByName(name) = result and
146+
exists(this.(PythonFunctionObjectInternal).getScope().getArgByName(name))
147+
or
148+
called instanceof BoundMethodObjectInternal and
149+
offset = 1 and name = "self" and result = call.getFunction().(AttrNode).getObject()
132150
)
133151
}
134152

python/ql/src/semmle/python/objects/ObjectInternal.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class ObjectInternal extends TObject {
103103
*/
104104
abstract int length();
105105

106+
predicate functionAndOffset(CallableObjectInternal function, int offset) { none() }
107+
106108
}
107109

108110

python/ql/src/semmle/python/types/FunctionObject.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ abstract class FunctionObject extends Object {
7171
This predicate will correctly handle `x.y()`, treating `x` as the zeroth argument.
7272
*/
7373
ControlFlowNode getArgumentForCall(CallNode call, int n) {
74-
result = theCallable().getArgumentForCall(call, this.getFunction().getArg(n).asName().getAFlowNode())
74+
result = theCallable().getArgumentForCall(call, n)
7575
}
7676

7777
/** Gets the `ControlFlowNode` that will be passed as the named argument to `this` when called at `call`.
7878
This predicate will correctly handle `x.y()`, treating `x` as the self argument.
7979
*/
8080
ControlFlowNode getNamedArgumentForCall(CallNode call, string name) {
81-
result = theCallable().getArgumentForCall(call, this.getFunction().getArgByName(name).asName().getAFlowNode())
81+
result = theCallable().getNamedArgumentForCall(call, name)
8282
}
8383

8484
/** Whether this function never returns. This is an approximation.

0 commit comments

Comments
 (0)