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

Skip to content

Commit f543adc

Browse files
committed
Python points-to: Fix up matching arguments to parameters.
1 parent 662aedc commit f543adc

4 files changed

Lines changed: 63 additions & 21 deletions

File tree

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ abstract class CallableObjectInternal extends ObjectInternal {
4646

4747
CallNode getACall() { result = this.getACall(_) }
4848

49+
abstract NameNode getParameter(int n);
50+
51+
abstract NameNode getParameterByName(string name);
52+
4953
}
5054

5155

@@ -132,6 +136,14 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
132136
)
133137
}
134138

139+
override NameNode getParameter(int n) {
140+
result.getNode() = this.getScope().getArg(n)
141+
}
142+
143+
override NameNode getParameterByName(string name) {
144+
result.getNode() = this.getScope().getArgByName(name)
145+
}
146+
135147
}
136148

137149

@@ -229,6 +241,13 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
229241
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
230242
}
231243

244+
override NameNode getParameter(int n) {
245+
none()
246+
}
247+
248+
override NameNode getParameterByName(string name) {
249+
none()
250+
}
232251

233252
}
234253

@@ -289,6 +308,14 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
289308
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
290309
}
291310

311+
override NameNode getParameter(int n) {
312+
none()
313+
}
314+
315+
override NameNode getParameterByName(string name) {
316+
none()
317+
}
318+
292319
}
293320

294321
class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
@@ -352,6 +379,14 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
352379
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
353380
}
354381

382+
override NameNode getParameter(int n) {
383+
result = this.getFunction().getParameter(n+1)
384+
}
385+
386+
override NameNode getParameterByName(string name) {
387+
result = this.getFunction().getParameterByName(name)
388+
}
389+
355390
}
356391

357392
class ClassMethodObjectInternal extends ObjectInternal, TClassMethod {

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

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,6 @@ class Value extends TObject {
5757
result = this.(ObjectInternal).getSource()
5858
}
5959

60-
/** Gets the `ControlFlowNode` that will be passed as the nth argument to `this` when called at `call`.
61-
This predicate will correctly handle `x.y()`, treating `x` as the zeroth argument.
62-
*/
63-
ControlFlowNode getArgumentForCall(CallNode call, int n) {
64-
// TO DO..
65-
none()
66-
}
67-
68-
/** Gets the `ControlFlowNode` that will be passed as the named argument to `this` when called at `call`.
69-
This predicate will correctly handle `x.y()`, treating `x` as the self argument.
70-
*/
71-
ControlFlowNode getNamedArgumentForCall(CallNode call, string name) {
72-
// TO DO..
73-
none()
74-
}
7560
}
7661

7762
class ModuleValue extends Value {
@@ -130,6 +115,28 @@ class CallableValue extends Value {
130115
result = this.(PythonFunctionObjectInternal).getScope()
131116
}
132117

118+
NameNode getParameter(int n) {
119+
result = this.(CallableObjectInternal).getParameter(n)
120+
}
121+
122+
NameNode getParameterByName(string name) {
123+
result = this.(CallableObjectInternal).getParameterByName(name)
124+
}
125+
126+
ControlFlowNode getArgumentForCall(CallNode call, NameNode param) {
127+
this.getACall() = call and
128+
(
129+
exists(int n | call.getArg(n) = result and param = this.getParameter(n))
130+
or
131+
exists(string name | call.getArgByName(name) = result and param = this.getParameterByName(name))
132+
)
133+
or
134+
exists(BoundMethodObjectInternal bm |
135+
result = getArgumentForCall(call, param) and
136+
this = bm.getFunction()
137+
)
138+
}
139+
133140
}
134141

135142
class ClassValue extends Value {

python/ql/src/semmle/python/security/TaintTracking.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,13 +1204,13 @@ library module TaintFlowImplementation {
12041204
exists(ParameterDefinition def |
12051205
def.getDefiningNode() = param and
12061206
exists(CallableValue func, CallNode call |
1207-
exists(int n | argument = func.getArgumentForCall(call, n) and param.getNode() = func.getScope().getArg(n))
1207+
call.getFunction().pointsTo() = func and
1208+
callee = caller.getCallee(call) |
1209+
exists(int n | param = func.getParameter(n) and argument = call.getArg(n))
12081210
or
1209-
exists(string name | argument = func.getNamedArgumentForCall(call, name) and param.getNode() = func.getScope().getArgByName(name))
1211+
exists(string name | param = func.getParameterByName(name) and argument = call.getArgByName(name))
12101212
or
12111213
class_initializer_argument(_, _, call, func, argument, param)
1212-
|
1213-
callee = caller.getCallee(call)
12141214
)
12151215
)
12161216
}

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, n)
74+
result = theCallable().getArgumentForCall(call, this.getFunction().getArg(n).asName().getAFlowNode())
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().getNamedArgumentForCall(call, name)
81+
result = theCallable().getArgumentForCall(call, this.getFunction().getArgByName(name).asName().getAFlowNode())
8282
}
8383

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

0 commit comments

Comments
 (0)