mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python points-to: Handle varargs in callee.
This commit is contained in:
@@ -227,6 +227,10 @@ class Call extends Call_ {
|
||||
result = this.getKwargs().(Dict).getAKey().(StrConst).getText()
|
||||
}
|
||||
|
||||
int getPositionalArgumentCount() {
|
||||
count(this.getStarargs()) < 2 and
|
||||
result = count(this.getAPositionalArg())
|
||||
}
|
||||
}
|
||||
|
||||
/** A conditional expression such as, `body if test else orelse` */
|
||||
|
||||
@@ -39,7 +39,9 @@ abstract class TupleObjectInternal extends SequenceObjectInternal {
|
||||
}
|
||||
|
||||
private string contents(int n) {
|
||||
n = this.length() and result = ""
|
||||
n < 4 and n = this.length() and result = ""
|
||||
or
|
||||
n = 4 and n < this.length() and result = "... " + (this.length()-4).toString() + " more"
|
||||
or
|
||||
result = this.getItem(n).toString() + ", " + this.contents(n+1)
|
||||
}
|
||||
@@ -145,6 +147,34 @@ class PythonTupleObjectInternal extends TPythonTuple, TupleObjectInternal {
|
||||
|
||||
}
|
||||
|
||||
class VarargsTupleObjectInternal extends TVarargsTuple, TupleObjectInternal {
|
||||
|
||||
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Builtin getBuiltin() {
|
||||
none()
|
||||
}
|
||||
|
||||
override ControlFlowNode getOrigin() {
|
||||
none()
|
||||
}
|
||||
|
||||
override ObjectInternal getItem(int n) {
|
||||
exists(CallNode call, PointsToContext context, int offset, int length |
|
||||
this = TVarargsTuple(call, context, offset, length) and
|
||||
n < length and
|
||||
PointsToInternal::pointsTo(call.getArg(offset+n), context, result, _)
|
||||
)
|
||||
}
|
||||
|
||||
override int length() {
|
||||
this = TVarargsTuple(_, _, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** The `sys.version_info` object. We treat this specially to prevent premature pruning and
|
||||
* false positives when we are unsure of the actual version of Python that the code is expecting.
|
||||
*/
|
||||
|
||||
@@ -179,6 +179,11 @@ cached newtype TObject =
|
||||
context.appliesTo(origin)
|
||||
}
|
||||
or
|
||||
/* Varargs tuple */
|
||||
TVarargsTuple(CallNode call, PointsToContext context, int offset, int length) {
|
||||
InterProceduralPointsTo::varargs_tuple(call, _, context, _, offset, length)
|
||||
}
|
||||
or
|
||||
/* `type` */
|
||||
TType()
|
||||
or
|
||||
|
||||
@@ -899,17 +899,38 @@ module InterProceduralPointsTo {
|
||||
pragma [noinline]
|
||||
private predicate special_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
special_parameter_value(def, value) and
|
||||
(
|
||||
context.isRuntime()
|
||||
or
|
||||
exists(PointsToContext caller, CallNode call |
|
||||
context.fromCall(call, caller) and
|
||||
context.appliesToScope(def.getScope()) and
|
||||
not exists(call.getArg(def.getParameter().getPosition())) and
|
||||
not exists(call.getArgByName(def.getParameter().getName()))
|
||||
)
|
||||
context.isRuntime() and
|
||||
origin = def.getDefiningNode()
|
||||
or
|
||||
exists(CallNode call, Function scope, PointsToContext caller, int offset, int length |
|
||||
varargs_tuple(call, scope, caller, context, offset, length) and
|
||||
value = TVarargsTuple(call, caller, offset, length) and
|
||||
def.getScope() = scope
|
||||
) and
|
||||
origin = def.getDefiningNode()
|
||||
or
|
||||
exists(Function scope |
|
||||
varargs_empty_tuple(scope, context) and
|
||||
value.(BuiltinTupleObjectInternal).length() = 0 and
|
||||
def.getScope() = scope
|
||||
) and
|
||||
origin = def.getDefiningNode()
|
||||
}
|
||||
|
||||
predicate varargs_tuple(CallNode call, Function scope, PointsToContext caller, PointsToContext callee, int startOffset, int length) {
|
||||
exists(int parameter_offset |
|
||||
callsite_calls_function(call, caller, scope, callee, parameter_offset) and
|
||||
startOffset = scope.getPositionalParameterCount() - parameter_offset and
|
||||
length = call.getNode().getPositionalArgumentCount() - startOffset and
|
||||
length > 0
|
||||
)
|
||||
}
|
||||
|
||||
predicate varargs_empty_tuple(Function scope, PointsToContext callee) {
|
||||
exists(CallNode call, PointsToContext caller, int parameter_offset |
|
||||
callsite_calls_function(call, caller, scope, callee, parameter_offset) and
|
||||
scope.getPositionalParameterCount() - parameter_offset >= call.getNode().getPositionalArgumentCount()
|
||||
)
|
||||
}
|
||||
|
||||
/** Helper predicate for special_parameter_points_to */
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
| l_calls.py:10 | ControlFlowNode for bar() | bar |
|
||||
| l_calls.py:24 | ControlFlowNode for Attribute() | Owner.cm |
|
||||
| l_calls.py:25 | ControlFlowNode for Attribute() | Owner.cm2 |
|
||||
| l_calls.py:37 | ControlFlowNode for f() | f |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute() | E.m |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute() | E.m |
|
||||
| q_super.py:4 | ControlFlowNode for Attribute() | object.__init__ |
|
||||
| q_super.py:12 | ControlFlowNode for Attribute() | Base2.__init__ |
|
||||
| q_super.py:22 | ControlFlowNode for Attribute() | Base1.meth |
|
||||
|
||||
@@ -112,12 +112,15 @@
|
||||
| k_getsetattr.py:0 | Module code.k_getsetattr | k | Function k |
|
||||
| k_getsetattr.py:4 | Class C | meth1 | Function meth1 |
|
||||
| k_getsetattr.py:4 | Class C | meth2 | Function meth2 |
|
||||
| l_calls.py:0 | Module code.l_calls | E | class E |
|
||||
| l_calls.py:0 | Module code.l_calls | Owner | class Owner |
|
||||
| l_calls.py:0 | Module code.l_calls | bar | Function bar |
|
||||
| l_calls.py:0 | Module code.l_calls | f | Function f |
|
||||
| l_calls.py:0 | Module code.l_calls | foo | Function foo |
|
||||
| l_calls.py:12 | Class Owner | cm | classmethod() |
|
||||
| l_calls.py:12 | Class Owner | cm2 | classmethod() |
|
||||
| l_calls.py:12 | Class Owner | m | Function m |
|
||||
| l_calls.py:32 | Class E | m | Function m |
|
||||
| o_no_returns.py:0 | Module code.o_no_returns | bar | Function bar |
|
||||
| o_no_returns.py:0 | Module code.o_no_returns | fail | Function fail |
|
||||
| o_no_returns.py:0 | Module code.o_no_returns | foo | Function foo |
|
||||
|
||||
@@ -598,6 +598,43 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
|
||||
| l_calls.py:25 | ControlFlowNode for Attribute() | int 1 | builtin-class int | 25 | runtime |
|
||||
| l_calls.py:25 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 25 | runtime |
|
||||
| l_calls.py:25 | ControlFlowNode for a | class Owner | builtin-class type | 12 | runtime |
|
||||
| l_calls.py:29 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 29 | import |
|
||||
| l_calls.py:29 | ControlFlowNode for args | args | builtin-class tuple | 29 | runtime |
|
||||
| l_calls.py:29 | ControlFlowNode for f | Function f | builtin-class function | 29 | import |
|
||||
| l_calls.py:30 | ControlFlowNode for args | args | builtin-class tuple | 29 | code/l_calls.py:37 from import |
|
||||
| l_calls.py:30 | ControlFlowNode for args | args | builtin-class tuple | 29 | runtime |
|
||||
| l_calls.py:32 | ControlFlowNode for ClassExpr | class E | builtin-class type | 32 | import |
|
||||
| l_calls.py:32 | ControlFlowNode for E | class E | builtin-class type | 32 | import |
|
||||
| l_calls.py:32 | ControlFlowNode for object | builtin-class object | builtin-class type | 32 | import |
|
||||
| l_calls.py:33 | ControlFlowNode for FunctionExpr | Function m | builtin-class function | 33 | import |
|
||||
| l_calls.py:33 | ControlFlowNode for args | args | builtin-class tuple | 33 | runtime |
|
||||
| l_calls.py:33 | ControlFlowNode for m | Function m | builtin-class function | 33 | import |
|
||||
| l_calls.py:34 | ControlFlowNode for self | E() | class E | 38 | code/l_calls.py:38 from import |
|
||||
| l_calls.py:34 | ControlFlowNode for self | int 3 | builtin-class int | 39 | code/l_calls.py:39 from import |
|
||||
| l_calls.py:34 | ControlFlowNode for self | self | builtin-class tuple | 33 | code/l_calls.py:38 from import |
|
||||
| l_calls.py:34 | ControlFlowNode for self | self | builtin-class tuple | 33 | code/l_calls.py:39 from import |
|
||||
| l_calls.py:34 | ControlFlowNode for self | self | class E | 33 | runtime |
|
||||
| l_calls.py:35 | ControlFlowNode for args | args | builtin-class tuple | 33 | code/l_calls.py:38 from import |
|
||||
| l_calls.py:35 | ControlFlowNode for args | args | builtin-class tuple | 33 | code/l_calls.py:39 from import |
|
||||
| l_calls.py:35 | ControlFlowNode for args | args | builtin-class tuple | 33 | runtime |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 37 | import |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 37 | import |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 37 | import |
|
||||
| l_calls.py:37 | ControlFlowNode for f | Function f | builtin-class function | 29 | import |
|
||||
| l_calls.py:37 | ControlFlowNode for f() | args | builtin-class tuple | 29 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute | Attribute | builtin-class method | 38 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute() | args | builtin-class tuple | 33 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for E | class E | builtin-class type | 32 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for E() | E() | class E | 38 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 38 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 38 | import |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 4 | builtin-class int | 38 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute | Function m | builtin-class function | 33 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute() | args | builtin-class tuple | 33 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for E | class E | builtin-class type | 32 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 39 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 4 | builtin-class int | 39 | import |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 5 | builtin-class int | 39 | import |
|
||||
| m_attributes.py:3 | ControlFlowNode for C | class C | builtin-class type | 3 | import |
|
||||
| m_attributes.py:3 | ControlFlowNode for ClassExpr | class C | builtin-class type | 3 | import |
|
||||
| m_attributes.py:3 | ControlFlowNode for object | builtin-class object | builtin-class type | 3 | import |
|
||||
|
||||
@@ -675,6 +675,39 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
|
||||
| l_calls.py:25 | ControlFlowNode for Attribute() | int 1 | builtin-class int | 25 |
|
||||
| l_calls.py:25 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 25 |
|
||||
| l_calls.py:25 | ControlFlowNode for a | class Owner | builtin-class type | 12 |
|
||||
| l_calls.py:29 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 29 |
|
||||
| l_calls.py:29 | ControlFlowNode for args | args | builtin-class tuple | 29 |
|
||||
| l_calls.py:29 | ControlFlowNode for f | Function f | builtin-class function | 29 |
|
||||
| l_calls.py:30 | ControlFlowNode for args | args | builtin-class tuple | 29 |
|
||||
| l_calls.py:32 | ControlFlowNode for ClassExpr | class E | builtin-class type | 32 |
|
||||
| l_calls.py:32 | ControlFlowNode for E | class E | builtin-class type | 32 |
|
||||
| l_calls.py:32 | ControlFlowNode for object | builtin-class object | builtin-class type | 32 |
|
||||
| l_calls.py:33 | ControlFlowNode for FunctionExpr | Function m | builtin-class function | 33 |
|
||||
| l_calls.py:33 | ControlFlowNode for args | args | builtin-class tuple | 33 |
|
||||
| l_calls.py:33 | ControlFlowNode for m | Function m | builtin-class function | 33 |
|
||||
| l_calls.py:34 | ControlFlowNode for self | E() | class E | 38 |
|
||||
| l_calls.py:34 | ControlFlowNode for self | int 3 | builtin-class int | 39 |
|
||||
| l_calls.py:34 | ControlFlowNode for self | self | builtin-class tuple | 33 |
|
||||
| l_calls.py:34 | ControlFlowNode for self | self | class E | 33 |
|
||||
| l_calls.py:35 | ControlFlowNode for args | args | builtin-class tuple | 33 |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 37 |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 37 |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 37 |
|
||||
| l_calls.py:37 | ControlFlowNode for f | Function f | builtin-class function | 29 |
|
||||
| l_calls.py:37 | ControlFlowNode for f() | args | builtin-class tuple | 29 |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute | Attribute | builtin-class method | 38 |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute() | args | builtin-class tuple | 33 |
|
||||
| l_calls.py:38 | ControlFlowNode for E | class E | builtin-class type | 32 |
|
||||
| l_calls.py:38 | ControlFlowNode for E() | E() | class E | 38 |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 38 |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 38 |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | int 4 | builtin-class int | 38 |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute | Function m | builtin-class function | 33 |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute() | args | builtin-class tuple | 33 |
|
||||
| l_calls.py:39 | ControlFlowNode for E | class E | builtin-class type | 32 |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 3 | builtin-class int | 39 |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 4 | builtin-class int | 39 |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | int 5 | builtin-class int | 39 |
|
||||
| s_scopes.py:4 | ControlFlowNode for True | bool True | builtin-class bool | 4 |
|
||||
| s_scopes.py:4 | ControlFlowNode for float | bool True | builtin-class bool | 4 |
|
||||
| s_scopes.py:7 | ControlFlowNode for C2 | class C2 | builtin-class type | 7 |
|
||||
|
||||
@@ -466,6 +466,38 @@
|
||||
| l_calls.py:25 | ControlFlowNode for Attribute() | runtime | int 1 | builtin-class int |
|
||||
| l_calls.py:25 | ControlFlowNode for IntegerLiteral | runtime | int 1 | builtin-class int |
|
||||
| l_calls.py:25 | ControlFlowNode for a | runtime | class Owner | builtin-class type |
|
||||
| l_calls.py:29 | ControlFlowNode for FunctionExpr | import | Function f | builtin-class function |
|
||||
| l_calls.py:30 | ControlFlowNode for args | code/l_calls.py:37 from import | (int 1, int 2, int 3, ) | builtin-class tuple |
|
||||
| l_calls.py:30 | ControlFlowNode for args | runtime | instance of tuple | builtin-class tuple |
|
||||
| l_calls.py:32 | ControlFlowNode for ClassExpr | import | class E | builtin-class type |
|
||||
| l_calls.py:32 | ControlFlowNode for object | import | builtin-class object | builtin-class type |
|
||||
| l_calls.py:33 | ControlFlowNode for FunctionExpr | import | Function E.m | builtin-class function |
|
||||
| l_calls.py:34 | ControlFlowNode for self | code/l_calls.py:38 from import | (int 2, int 3, int 4, ) | builtin-class tuple |
|
||||
| l_calls.py:34 | ControlFlowNode for self | code/l_calls.py:38 from import | E() | class E |
|
||||
| l_calls.py:34 | ControlFlowNode for self | code/l_calls.py:39 from import | (int 4, int 5, ) | builtin-class tuple |
|
||||
| l_calls.py:34 | ControlFlowNode for self | code/l_calls.py:39 from import | int 3 | builtin-class int |
|
||||
| l_calls.py:34 | ControlFlowNode for self | runtime | self instance of E | class E |
|
||||
| l_calls.py:35 | ControlFlowNode for args | code/l_calls.py:38 from import | (int 2, int 3, int 4, ) | builtin-class tuple |
|
||||
| l_calls.py:35 | ControlFlowNode for args | code/l_calls.py:39 from import | (int 4, int 5, ) | builtin-class tuple |
|
||||
| l_calls.py:35 | ControlFlowNode for args | runtime | instance of tuple | builtin-class tuple |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | import | int 1 | builtin-class int |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | import | int 2 | builtin-class int |
|
||||
| l_calls.py:37 | ControlFlowNode for IntegerLiteral | import | int 3 | builtin-class int |
|
||||
| l_calls.py:37 | ControlFlowNode for f | import | Function f | builtin-class function |
|
||||
| l_calls.py:37 | ControlFlowNode for f() | import | (int 1, int 2, int 3, ) | builtin-class tuple |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute | import | Method(Function E.m, E()) | builtin-class method |
|
||||
| l_calls.py:38 | ControlFlowNode for Attribute() | import | (int 2, int 3, int 4, ) | builtin-class tuple |
|
||||
| l_calls.py:38 | ControlFlowNode for E | import | class E | builtin-class type |
|
||||
| l_calls.py:38 | ControlFlowNode for E() | import | E() | class E |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | import | int 2 | builtin-class int |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | import | int 3 | builtin-class int |
|
||||
| l_calls.py:38 | ControlFlowNode for IntegerLiteral | import | int 4 | builtin-class int |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute | import | Function E.m | builtin-class function |
|
||||
| l_calls.py:39 | ControlFlowNode for Attribute() | import | (int 4, int 5, ) | builtin-class tuple |
|
||||
| l_calls.py:39 | ControlFlowNode for E | import | class E | builtin-class type |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | import | int 3 | builtin-class int |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | import | int 4 | builtin-class int |
|
||||
| l_calls.py:39 | ControlFlowNode for IntegerLiteral | import | int 5 | builtin-class int |
|
||||
| m_attributes.py:3 | ControlFlowNode for ClassExpr | import | class C | builtin-class type |
|
||||
| m_attributes.py:3 | ControlFlowNode for object | import | builtin-class object | builtin-class type |
|
||||
| m_attributes.py:5 | ControlFlowNode for FunctionExpr | import | Function C.__init__ | builtin-class function |
|
||||
|
||||
@@ -24,3 +24,16 @@ class Owner(object):
|
||||
a = self.cm(0)
|
||||
return a.cm2(1)
|
||||
|
||||
# *args
|
||||
|
||||
def f(*args):
|
||||
return args
|
||||
|
||||
class E(object):
|
||||
def m(self, *args):
|
||||
self
|
||||
return args
|
||||
|
||||
f(1, 2, 3)
|
||||
E().m(2, 3, 4)
|
||||
E.m(3, 4, 5)
|
||||
|
||||
Reference in New Issue
Block a user