mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
Python points-to: Clean up interface, and deprecate old interface.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
|
||||
/** An expression */
|
||||
class Expr extends Expr_, AstNode {
|
||||
@@ -86,7 +86,7 @@ class Expr extends Expr_, AstNode {
|
||||
*/
|
||||
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
|
||||
exists(Value value, ControlFlowNode cfgorigin |
|
||||
PointsTo2::pointsTo(this.getAFlowNode(), context, value, cfgorigin) and
|
||||
PointsTo::pointsTo(this.getAFlowNode(), context, value, cfgorigin) and
|
||||
origin.getAFlowNode() = cfgorigin and
|
||||
cls = value.getClass().getSource() |
|
||||
if exists(value.getSource()) then
|
||||
@@ -102,7 +102,7 @@ class Expr extends Expr_, AstNode {
|
||||
*/
|
||||
predicate refersTo(Object obj, AstNode origin) {
|
||||
exists(Value value, ControlFlowNode cfgorigin |
|
||||
PointsTo2::pointsTo(this.getAFlowNode(), _, value, cfgorigin) and
|
||||
PointsTo::pointsTo(this.getAFlowNode(), _, value, cfgorigin) and
|
||||
origin.getAFlowNode() = cfgorigin and
|
||||
if exists(value.getSource()) then
|
||||
obj = value.getSource()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import semmle.python.flow.NameNode
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
|
||||
|
||||
/* Note about matching parent and child nodes and CFG splitting:
|
||||
@@ -224,7 +224,7 @@ class ControlFlowNode extends @py_flow_node {
|
||||
|
||||
/** The value and origin that this ControlFlowNode points-to, given the context. */
|
||||
predicate pointsTo(Context context, Value value, ControlFlowNode origin) {
|
||||
PointsTo2::pointsTo(this, context, value, origin)
|
||||
PointsTo::pointsTo(this, context, value, origin)
|
||||
}
|
||||
|
||||
/** Gets what this flow node might "refer-to". Performs a combination of localized (intra-procedural) points-to
|
||||
@@ -240,7 +240,7 @@ class ControlFlowNode extends @py_flow_node {
|
||||
*/
|
||||
predicate refersTo(Context context, Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
exists(Value value |
|
||||
PointsTo2::pointsTo(this, context, value, origin) and
|
||||
PointsTo::pointsTo(this, context, value, origin) and
|
||||
cls = value.getClass().getSource() |
|
||||
if exists(value.getSource().(Object)) then
|
||||
obj = value.getSource()
|
||||
@@ -255,7 +255,7 @@ class ControlFlowNode extends @py_flow_node {
|
||||
*/
|
||||
predicate refersTo(Object obj, ControlFlowNode origin) {
|
||||
exists(Value value |
|
||||
PointsTo2::pointsTo(this, _, value, origin) |
|
||||
PointsTo::pointsTo(this, _, value, origin) |
|
||||
if exists(value.getSource().(Object)) then
|
||||
obj = value.getSource()
|
||||
else
|
||||
|
||||
@@ -3,7 +3,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.types.Builtins
|
||||
@@ -42,6 +42,10 @@ abstract class CallableObjectInternal extends ObjectInternal {
|
||||
|
||||
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
|
||||
|
||||
abstract CallNode getACall(PointsToContext ctx);
|
||||
|
||||
CallNode getACall() { result = this.getACall(_) }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -81,11 +85,11 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
|
||||
func = this.getScope() and
|
||||
callee.appliesToScope(func) |
|
||||
rval = func.getAReturnValueFlowNode() and
|
||||
PointsTo2::pointsTo(rval, callee, obj, origin)
|
||||
PointsToInternal::pointsTo(rval, callee, obj, origin)
|
||||
or
|
||||
exists(Return ret |
|
||||
ret.getScope() = func and
|
||||
PointsTo2::reachableBlock(ret.getAFlowNode().getBasicBlock(), callee) and
|
||||
PointsToInternal::reachableBlock(ret.getAFlowNode().getBasicBlock(), callee) and
|
||||
not exists(ret.getValue()) and
|
||||
obj = ObjectInternal::none_() and
|
||||
origin = CfgOrigin::unknown()
|
||||
@@ -113,6 +117,14 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
|
||||
value = TBoundMethod(instance, this) and origin = CfgOrigin::unknown()
|
||||
}
|
||||
|
||||
override CallNode getACall(PointsToContext ctx) {
|
||||
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
|
||||
or
|
||||
exists(BoundMethodObjectInternal bm |
|
||||
bm.getACall() = result and this = bm.getFunction()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunctionObject {
|
||||
@@ -192,6 +204,10 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
|
||||
|
||||
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
|
||||
|
||||
override CallNode getACall(PointsToContext ctx) {
|
||||
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -248,6 +264,10 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
|
||||
value = this and origin = CfgOrigin::unknown()
|
||||
}
|
||||
|
||||
override CallNode getACall(PointsToContext ctx) {
|
||||
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
|
||||
@@ -307,6 +327,10 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
|
||||
|
||||
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
|
||||
|
||||
override CallNode getACall(PointsToContext ctx) {
|
||||
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ClassMethodObjectInternal extends ObjectInternal, TClassMethod {
|
||||
|
||||
@@ -3,7 +3,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.types.Builtins
|
||||
@@ -39,7 +39,7 @@ abstract class ClassObjectInternal extends ObjectInternal {
|
||||
|
||||
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
|
||||
instance = this and
|
||||
PointsTo2::attributeRequired(this, name) and
|
||||
PointsToInternal::attributeRequired(this, name) and
|
||||
this.attribute(name, descriptor, _) and
|
||||
descriptor.isDescriptor() = true
|
||||
}
|
||||
@@ -236,7 +236,7 @@ class TypeInternal extends ClassObjectInternal, TType {
|
||||
exists(CallNode call, PointsToContext caller, ObjectInternal instance |
|
||||
callee.fromCall(call, caller) |
|
||||
count(call.getAnArg()) = 1 and
|
||||
PointsTo2::pointsTo(call.getArg(0), caller, instance, origin) and
|
||||
PointsToInternal::pointsTo(call.getArg(0), caller, instance, origin) and
|
||||
obj = instance.getClass()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.types.Builtins
|
||||
|
||||
@@ -3,7 +3,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.types.Builtins
|
||||
@@ -77,7 +77,7 @@ class SpecificInstanceInternal extends TSpecificInstance, ObjectInternal {
|
||||
}
|
||||
|
||||
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
|
||||
PointsTo2::attributeRequired(this, name) and
|
||||
PointsToInternal::attributeRequired(this, name) and
|
||||
instance_getattr(this, Types::getMro(this.getClass()), name, value, origin)
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class SpecificInstanceInternal extends TSpecificInstance, ObjectInternal {
|
||||
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
|
||||
this = instance and descriptor.isDescriptor() = true and
|
||||
exists(AttrNode attr |
|
||||
PointsTo2::pointsTo(attr.getObject(name), _, instance, _) and
|
||||
PointsToInternal::pointsTo(attr.getObject(name), _, instance, _) and
|
||||
this.getClass().attribute(name, descriptor, _)
|
||||
)
|
||||
}
|
||||
@@ -186,7 +186,7 @@ class SelfInstanceInternal extends TSelfInstance, ObjectInternal {
|
||||
}
|
||||
|
||||
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
|
||||
PointsTo2::attributeRequired(this, name) and
|
||||
PointsToInternal::attributeRequired(this, name) and
|
||||
instance_getattr(this, Types::getMro(this.getClass()), name, value, origin)
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ class SelfInstanceInternal extends TSelfInstance, ObjectInternal {
|
||||
descriptor.isDescriptor() = true and
|
||||
this = instance and
|
||||
exists(AttrNode attr |
|
||||
PointsTo2::pointsTo(attr.getObject(name), _, this, _) and
|
||||
PointsToInternal::pointsTo(attr.getObject(name), _, this, _) and
|
||||
this.getClass().attribute(name, descriptor, _)
|
||||
)
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class UnknownInstanceInternal extends TUnknownInstance, ObjectInternal {
|
||||
}
|
||||
|
||||
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
|
||||
PointsTo2::attributeRequired(this, name) and
|
||||
PointsToInternal::attributeRequired(this, name) and
|
||||
instance_getattr(this, Types::getMro(this.getClass()), name, value, origin)
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ class UnknownInstanceInternal extends TUnknownInstance, ObjectInternal {
|
||||
descriptor.isDescriptor() = true and
|
||||
this = instance and
|
||||
exists(AttrNode attr |
|
||||
PointsTo2::pointsTo(attr.getObject(name), _, this, _) and
|
||||
PointsToInternal::pointsTo(attr.getObject(name), _, this, _) and
|
||||
this.getClass().attribute(name, descriptor, _)
|
||||
)
|
||||
}
|
||||
@@ -355,7 +355,7 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
|
||||
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
|
||||
|
||||
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
|
||||
PointsTo2::attributeRequired(this, name) and
|
||||
PointsToInternal::attributeRequired(this, name) and
|
||||
instance_getattr(this.getSelf(), this.getMro(), name, value, origin)
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
|
||||
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
|
||||
descriptor.isDescriptor() = true and
|
||||
exists(AttrNode attr |
|
||||
PointsTo2::pointsTo(attr.getObject(name), _, this, _) and
|
||||
PointsToInternal::pointsTo(attr.getObject(name), _, this, _) and
|
||||
instance = this.getSelf() and
|
||||
Types::declaredAttribute(this.getMro().findDeclaringClass(name), name, descriptor, _)
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.types.Builtins
|
||||
@@ -233,7 +233,7 @@ class PythonModuleObjectInternal extends ModuleObjectInternal, TPythonModule {
|
||||
exists(EssaVariable var, ControlFlowNode exit, PointsToContext imp |
|
||||
exit = this.getSourceModule().getANormalExit() and var.getAUse() = exit and
|
||||
var.getSourceVariable().getName() = name and
|
||||
PointsTo2::ssa_variable_pointsTo(var, imp, value, origin) and
|
||||
PointsTo::variablePointsTo(var, imp, value, origin) and
|
||||
imp.isImport() and
|
||||
value != ObjectInternal::undefined()
|
||||
)
|
||||
@@ -242,7 +242,7 @@ class PythonModuleObjectInternal extends ModuleObjectInternal, TPythonModule {
|
||||
//not exists(EssaVariable var | var.getAUse() = m.getANormalExit() and var.getSourceVariable().getName() = name) and
|
||||
//exists(EssaVariable var, PointsToContext imp |
|
||||
// var.getAUse() = m.getANormalExit() and isModuleStateVariable(var) |
|
||||
// PointsTo2::ssa_variable_named_attribute_pointsTo(var, imp, name, obj, origin) and
|
||||
// PointsToInternal::ssa_variable_named_attribute_pointsTo(var, imp, name, obj, origin) and
|
||||
// imp.isImport() and obj != ObjectInternal::undefined()
|
||||
//)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import python
|
||||
private import TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
|
||||
class ObjectSource = Object;
|
||||
@@ -19,11 +19,11 @@ class Value extends TObject {
|
||||
}
|
||||
|
||||
ControlFlowNode getAReference() {
|
||||
PointsTo2::pointsTo(result, _, this, _)
|
||||
PointsToInternal::pointsTo(result, _, this, _)
|
||||
}
|
||||
|
||||
predicate pointsTo(ControlFlowNode node, PointsToContext context, ControlFlowNode origin) {
|
||||
PointsTo2::pointsTo(node, context, this, origin)
|
||||
PointsToInternal::pointsTo(node, context, this, origin)
|
||||
}
|
||||
|
||||
Value getClass() {
|
||||
@@ -31,10 +31,19 @@ class Value extends TObject {
|
||||
}
|
||||
|
||||
CallNode getACall() {
|
||||
PointsTo2::pointsTo(result.getFunction(), _, this, _)
|
||||
PointsToInternal::pointsTo(result.getFunction(), _, this, _)
|
||||
or
|
||||
exists(BoundMethodObjectInternal bm |
|
||||
PointsTo2::pointsTo(result.getFunction(), _, bm, _) and
|
||||
PointsToInternal::pointsTo(result.getFunction(), _, bm, _) and
|
||||
bm.getFunction() = this
|
||||
)
|
||||
}
|
||||
|
||||
CallNode getACall(PointsToContext caller) {
|
||||
PointsToInternal::pointsTo(result.getFunction(), caller, this, _)
|
||||
or
|
||||
exists(BoundMethodObjectInternal bm |
|
||||
PointsToInternal::pointsTo(result.getFunction(), caller, bm, _) and
|
||||
bm.getFunction() = this
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.types.Builtins
|
||||
|
||||
@@ -6,7 +6,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.types.Builtins
|
||||
@@ -125,7 +125,7 @@ class PythonTupleObjectInternal extends TPythonTuple, TupleObjectInternal {
|
||||
override ObjectInternal getItem(int n) {
|
||||
exists(TupleNode t, PointsToContext context |
|
||||
this = TPythonTuple(t, context) and
|
||||
PointsTo2::pointsTo(t.getElement(n), context, result, _)
|
||||
PointsToInternal::pointsTo(t.getElement(n), context, result, _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import python
|
||||
private import semmle.python.types.Builtins
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
|
||||
newtype TObject =
|
||||
@@ -83,7 +83,7 @@ newtype TObject =
|
||||
}
|
||||
or
|
||||
TSpecificInstance(ControlFlowNode instantiation, ClassObjectInternal cls, PointsToContext context) {
|
||||
PointsTo2::pointsTo(instantiation.(CallNode).getFunction(), context, cls, _) and
|
||||
PointsToInternal::pointsTo(instantiation.(CallNode).getFunction(), context, cls, _) and
|
||||
cls.isSpecial() = false
|
||||
or
|
||||
literal_instantiation(instantiation, cls, context)
|
||||
@@ -128,13 +128,13 @@ private predicate is_power_2(int n) {
|
||||
}
|
||||
|
||||
predicate static_method(CallNode instantiation, CallableObjectInternal function, PointsToContext context) {
|
||||
PointsTo2::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("staticmethod"), _) and
|
||||
PointsTo2::pointsTo(instantiation.getArg(0), context, function, _)
|
||||
PointsToInternal::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("staticmethod"), _) and
|
||||
PointsToInternal::pointsTo(instantiation.getArg(0), context, function, _)
|
||||
}
|
||||
|
||||
predicate class_method(CallNode instantiation, CallableObjectInternal function, PointsToContext context) {
|
||||
PointsTo2::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("classmethod"), _) and
|
||||
PointsTo2::pointsTo(instantiation.getArg(0), context, function, _)
|
||||
PointsToInternal::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("classmethod"), _) and
|
||||
PointsToInternal::pointsTo(instantiation.getArg(0), context, function, _)
|
||||
}
|
||||
|
||||
predicate literal_instantiation(ControlFlowNode n, ClassObjectInternal cls, PointsToContext context) {
|
||||
@@ -149,10 +149,10 @@ predicate literal_instantiation(ControlFlowNode n, ClassObjectInternal cls, Poin
|
||||
}
|
||||
|
||||
predicate super_instantiation(CallNode instantiation, ObjectInternal self, ClassObjectInternal startclass, PointsToContext context) {
|
||||
PointsTo2::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("super"), _) and
|
||||
PointsToInternal::pointsTo(instantiation.getFunction(), context, ObjectInternal::builtin("super"), _) and
|
||||
(
|
||||
PointsTo2::pointsTo(instantiation.getArg(0), context, startclass, _) and
|
||||
PointsTo2::pointsTo(instantiation.getArg(1), context, self, _)
|
||||
PointsToInternal::pointsTo(instantiation.getArg(0), context, startclass, _) and
|
||||
PointsToInternal::pointsTo(instantiation.getArg(1), context, self, _)
|
||||
or
|
||||
major_version() = 3 and
|
||||
not exists(instantiation.getArg(0)) and
|
||||
@@ -161,7 +161,7 @@ predicate super_instantiation(CallNode instantiation, ObjectInternal self, Class
|
||||
/* Implicit class argument is lexically enclosing scope */
|
||||
func.getScope() = startclass.(PythonClassObjectInternal).getScope() and
|
||||
/* Implicit 'self' is the 0th parameter */
|
||||
PointsTo2::pointsTo(func.getArg(0).asName().getAFlowNode(), context, self, _)
|
||||
PointsToInternal::pointsTo(func.getArg(0).asName().getAFlowNode(), context, self, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -192,7 +192,7 @@ predicate method_binding(AttrNode instantiation, ObjectInternal self, CallableOb
|
||||
/** Helper for method_binding */
|
||||
pragma [noinline]
|
||||
predicate receiver(AttrNode instantiation, PointsToContext context, ObjectInternal obj, string name) {
|
||||
PointsTo2::pointsTo(instantiation.getObject(name), context, obj, _)
|
||||
PointsToInternal::pointsTo(instantiation.getObject(name), context, obj, _)
|
||||
}
|
||||
|
||||
/** Helper self parameters: `def meth(self, ...): ...`. */
|
||||
@@ -247,7 +247,7 @@ private predicate neither_class_nor_static_method(Function f) {
|
||||
exists(ControlFlowNode deco |
|
||||
deco = f.getADecorator().getAFlowNode() |
|
||||
exists(ObjectInternal o |
|
||||
PointsTo2::pointsTo(deco, _, o, _) |
|
||||
PointsToInternal::pointsTo(deco, _, o, _) |
|
||||
o != ObjectInternal::staticMethod() and
|
||||
o != ObjectInternal::classMethod()
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ import python
|
||||
|
||||
private import semmle.python.objects.TObject
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.PointsToContext
|
||||
private import semmle.python.types.Builtins
|
||||
|
||||
|
||||
@@ -93,37 +93,77 @@ module CfgOrigin {
|
||||
|
||||
}
|
||||
|
||||
cached module PointsTo2 {
|
||||
/* The API */
|
||||
module PointsTo {
|
||||
|
||||
predicate pointsTo(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
PointsToInternal::pointsTo(f, context, value, origin)
|
||||
}
|
||||
|
||||
predicate variablePointsTo(EssaVariable var, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
PointsToInternal::variablePointsTo(var, context, value, origin)
|
||||
}
|
||||
|
||||
/* Backwards compatibility */
|
||||
deprecated predicate
|
||||
points_to(ControlFlowNode f, PointsToContext context, Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
exists(Value value |
|
||||
PointsToInternal::pointsTo(f, context, value, origin) and
|
||||
obj = value.getSource() and
|
||||
cls = value.getClass().getSource()
|
||||
)
|
||||
}
|
||||
|
||||
deprecated predicate
|
||||
ssa_variable_points_to(EssaVariable var, PointsToContext context, Object obj, ClassObject cls, CfgOrigin origin) {
|
||||
exists(Value value |
|
||||
PointsToInternal::variablePointsTo(var, context, value, origin) and
|
||||
obj = value.getSource() and
|
||||
cls = value.getClass().getSource()
|
||||
)
|
||||
}
|
||||
|
||||
deprecated
|
||||
CallNode get_a_call(Object func, PointsToContext context) {
|
||||
exists(Value value |
|
||||
result = value.getACall(context) and
|
||||
func = value.getSource()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cached module PointsToInternal {
|
||||
|
||||
/** INTERNAL -- Use `f.refersTo(value, origin)` instead. */
|
||||
cached predicate pointsTo(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
pointsTo_candidate(f, context, value, origin) and
|
||||
points_to_candidate(f, context, value, origin) and
|
||||
reachableBlock(f.getBasicBlock(), context)
|
||||
}
|
||||
|
||||
private predicate pointsTo_candidate(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
use_pointsTo(f, context, value, origin)
|
||||
private predicate points_to_candidate(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
use_points_to(f, context, value, origin)
|
||||
or
|
||||
/* Not necessary, but for backwards compatibility */
|
||||
def_pointsTo(f, context, value, origin)
|
||||
def_points_to(f, context, value, origin)
|
||||
or
|
||||
attribute_load_pointsTo(f, context, value, origin)
|
||||
attribute_load_points_to(f, context, value, origin)
|
||||
or
|
||||
subscript_pointsTo(f, context, value, origin)
|
||||
subscript_points_to(f, context, value, origin)
|
||||
or
|
||||
binary_expr_pointsTo(f, context, value, origin)
|
||||
binary_expr_points_to(f, context, value, origin)
|
||||
or
|
||||
origin = f and compare_expr_pointsTo(f, context, value)
|
||||
origin = f and compare_expr_points_to(f, context, value)
|
||||
or
|
||||
origin = f and unary_pointsTo(f, context, value)
|
||||
origin = f and unary_points_to(f, context, value)
|
||||
or
|
||||
origin = f and value.introduced(f, context)
|
||||
or
|
||||
InterModulePointsTo::import_pointsTo(f, context, value, origin)
|
||||
InterModulePointsTo::import_points_to(f, context, value, origin)
|
||||
or
|
||||
InterModulePointsTo::from_import_pointsTo(f, context, value, origin)
|
||||
InterModulePointsTo::from_import_points_to(f, context, value, origin)
|
||||
or
|
||||
InterProceduralPointsTo::call_pointsTo(f, context, value, origin)
|
||||
InterProceduralPointsTo::call_points_to(f, context, value, origin)
|
||||
// To do... More stuff here :)
|
||||
// or
|
||||
// f.(CustomPointsToFact).pointsTo(context, value, origin)
|
||||
@@ -141,10 +181,6 @@ cached module PointsTo2 {
|
||||
)
|
||||
}
|
||||
|
||||
cached CallNode get_a_call(ObjectInternal func, PointsToContext context) {
|
||||
pointsTo(result.getFunction(), context, func, _)
|
||||
}
|
||||
|
||||
/* Holds if BasicBlock `b` is reachable, given the context `context`. */
|
||||
cached predicate reachableBlock(BasicBlock b, PointsToContext context) {
|
||||
context.appliesToScope(b.getScope()) and not exists(ConditionBlock guard | guard.controls(b, _))
|
||||
@@ -189,63 +225,63 @@ cached module PointsTo2 {
|
||||
|
||||
/** Gets an object pointed to by a use (of a variable). */
|
||||
pragma [noinline]
|
||||
private predicate use_pointsTo(NameNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate use_points_to(NameNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(CfgOrigin origin_or_obj |
|
||||
value != ObjectInternal::undefined() and
|
||||
use_pointsTo_maybe_origin(f, context, value, origin_or_obj) |
|
||||
use_points_to_maybe_origin(f, context, value, origin_or_obj) |
|
||||
origin = origin_or_obj.asCfgNodeOrHere(f)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets an object pointed to by the definition of an ESSA variable. */
|
||||
pragma [noinline]
|
||||
private predicate def_pointsTo(DefinitionNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate def_points_to(DefinitionNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
pointsTo(f.getValue(), context, value, origin)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate use_pointsTo_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
ssa_variable_pointsTo(fast_local_variable(f), context, value, origin_or_obj)
|
||||
private predicate use_points_to_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
variablePointsTo(fast_local_variable(f), context, value, origin_or_obj)
|
||||
or
|
||||
name_lookup_pointsTo_maybe_origin(f, context, value, origin_or_obj)
|
||||
name_lookup_points_to_maybe_origin(f, context, value, origin_or_obj)
|
||||
or
|
||||
not exists(fast_local_variable(f)) and not exists(name_local_variable(f)) and
|
||||
global_lookup_pointsTo_maybe_origin(f, context, value, origin_or_obj)
|
||||
global_lookup_points_to_maybe_origin(f, context, value, origin_or_obj)
|
||||
}
|
||||
|
||||
/** Holds if `var` refers to `(value, origin)` given the context `context`. */
|
||||
pragma [noinline]
|
||||
cached predicate ssa_variable_pointsTo(EssaVariable var, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
ssa_definition_pointsTo(var.getDefinition(), context, value, origin)
|
||||
cached predicate variablePointsTo(EssaVariable var, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
ssa_definition_points_to(var.getDefinition(), context, value, origin)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate name_lookup_pointsTo_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
private predicate name_lookup_points_to_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
exists(EssaVariable var | var = name_local_variable(f) |
|
||||
ssa_variable_pointsTo(var, context, value, origin_or_obj)
|
||||
variablePointsTo(var, context, value, origin_or_obj)
|
||||
)
|
||||
or
|
||||
local_variable_undefined(f, context) and
|
||||
global_lookup_pointsTo_maybe_origin(f, context, value, origin_or_obj)
|
||||
global_lookup_points_to_maybe_origin(f, context, value, origin_or_obj)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate local_variable_undefined(NameNode f, PointsToContext context) {
|
||||
ssa_variable_pointsTo(name_local_variable(f), context, ObjectInternal::undefined(), _)
|
||||
variablePointsTo(name_local_variable(f), context, ObjectInternal::undefined(), _)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate global_lookup_pointsTo_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
ssa_variable_pointsTo(global_variable(f), context, value, origin_or_obj)
|
||||
private predicate global_lookup_points_to_maybe_origin(NameNode f, PointsToContext context, ObjectInternal value, CfgOrigin origin_or_obj) {
|
||||
variablePointsTo(global_variable(f), context, value, origin_or_obj)
|
||||
or
|
||||
exists(ControlFlowNode origin |
|
||||
origin_or_obj = CfgOrigin::fromCfgNode(origin)
|
||||
|
|
||||
ssa_variable_pointsTo(global_variable(f), context, ObjectInternal::undefined(), _) and
|
||||
potential_builtin_pointsTo(f, value, origin)
|
||||
variablePointsTo(global_variable(f), context, ObjectInternal::undefined(), _) and
|
||||
potential_builtin_points_to(f, value, origin)
|
||||
or
|
||||
not exists(global_variable(f)) and context.appliesToScope(f.getScope()) and
|
||||
potential_builtin_pointsTo(f, value, origin)
|
||||
potential_builtin_points_to(f, value, origin)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -272,7 +308,7 @@ cached module PointsTo2 {
|
||||
|
||||
/** Holds if `f` is an attribute `x.attr` and points to `(value, cls, origin)`. */
|
||||
pragma [noinline]
|
||||
private predicate attribute_load_pointsTo(AttrNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate attribute_load_points_to(AttrNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
f.isLoad() and
|
||||
exists(ObjectInternal object, string name, CfgOrigin orig |
|
||||
pointsTo(f.getObject(name), context, object, _) |
|
||||
@@ -291,77 +327,77 @@ cached module PointsTo2 {
|
||||
}
|
||||
|
||||
/** Holds if the ESSA definition `def` refers to `(value, origin)` given the context `context`. */
|
||||
private predicate ssa_definition_pointsTo(EssaDefinition def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
ssa_phi_pointsTo(def, context, value, origin)
|
||||
private predicate ssa_definition_points_to(EssaDefinition def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
ssa_phi_points_to(def, context, value, origin)
|
||||
or
|
||||
exists(ControlFlowNode orig |
|
||||
ssa_node_definition_pointsTo(def, context, value, orig) and
|
||||
ssa_node_definition_points_to(def, context, value, orig) and
|
||||
origin = CfgOrigin::fromCfgNode(orig)
|
||||
)
|
||||
or
|
||||
ssa_filter_definition_pointsTo(def, context, value, origin)
|
||||
ssa_filter_definition_points_to(def, context, value, origin)
|
||||
or
|
||||
ssa_node_refinement_pointsTo(def, context, value, origin)
|
||||
ssa_node_refinement_points_to(def, context, value, origin)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate ssa_node_definition_pointsTo(EssaNodeDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate ssa_node_definition_points_to(EssaNodeDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
reachableBlock(def.getDefiningNode().getBasicBlock(), _) and
|
||||
ssa_node_definition_pointsTo_unpruned(def, context, value, origin)
|
||||
ssa_node_definition_points_to_unpruned(def, context, value, origin)
|
||||
}
|
||||
|
||||
pragma [nomagic]
|
||||
private predicate ssa_node_definition_pointsTo_unpruned(EssaNodeDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
InterProceduralPointsTo::parameter_pointsTo(def, context, value, origin)
|
||||
private predicate ssa_node_definition_points_to_unpruned(EssaNodeDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
InterProceduralPointsTo::parameter_points_to(def, context, value, origin)
|
||||
or
|
||||
assignment_pointsTo(def, context, value, origin)
|
||||
assignment_points_to(def, context, value, origin)
|
||||
//// TO DO...
|
||||
or
|
||||
self_parameter_pointsTo(def, context, value, origin)
|
||||
self_parameter_points_to(def, context, value, origin)
|
||||
or
|
||||
delete_pointsTo(def, context, value, origin)
|
||||
delete_points_to(def, context, value, origin)
|
||||
or
|
||||
module_name_pointsTo(def, context, value, origin)
|
||||
module_name_points_to(def, context, value, origin)
|
||||
or
|
||||
scope_entry_pointsTo(def, context, value, origin)
|
||||
scope_entry_points_to(def, context, value, origin)
|
||||
or
|
||||
InterModulePointsTo::implicit_submodule_pointsTo(def, context, value, origin)
|
||||
InterModulePointsTo::implicit_submodule_points_to(def, context, value, origin)
|
||||
// or
|
||||
// iteration_definition_pointsTo(def, context, value, origin)
|
||||
// iteration_definition_points_to(def, context, value, origin)
|
||||
/*
|
||||
* No points-to for non-local function entry definitions yet.
|
||||
*/
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate ssa_node_refinement_pointsTo(EssaNodeRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
//method_callsite_pointsTo(def, context, value, origin)
|
||||
private predicate ssa_node_refinement_points_to(EssaNodeRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
//method_callsite_points_to(def, context, value, origin)
|
||||
//or
|
||||
InterModulePointsTo::import_star_pointsTo(def, context, value, origin)
|
||||
InterModulePointsTo::import_star_points_to(def, context, value, origin)
|
||||
or
|
||||
//attribute_assignment_pointsTo(def, context, value, origin)
|
||||
//attribute_assignment_points_to(def, context, value, origin)
|
||||
//or
|
||||
InterProceduralPointsTo::callsite_pointsTo(def, context, value, origin)
|
||||
InterProceduralPointsTo::callsite_points_to(def, context, value, origin)
|
||||
or
|
||||
argument_pointsTo(def, context, value, origin)
|
||||
argument_points_to(def, context, value, origin)
|
||||
//or
|
||||
//attribute_delete_pointsTo(def, context, value, origin)
|
||||
//attribute_delete_points_to(def, context, value, origin)
|
||||
or
|
||||
uni_edged_phi_pointsTo(def, context, value, origin)
|
||||
uni_edged_phi_points_to(def, context, value, origin)
|
||||
}
|
||||
|
||||
/** Ignore the effects of calls on their arguments. PointsTo is an approximation, but attempting to improve accuracy would be very expensive for very little gain. */
|
||||
private predicate argument_pointsTo(ArgumentRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
ssa_variable_pointsTo(def.getInput(), context, value, origin)
|
||||
private predicate argument_points_to(ArgumentRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
variablePointsTo(def.getInput(), context, value, origin)
|
||||
}
|
||||
|
||||
private predicate self_parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
private predicate self_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
origin = CfgOrigin::fromCfgNode(def.getDefiningNode()) and
|
||||
value.(SelfInstanceInternal).parameterAndContext(def, context)
|
||||
}
|
||||
|
||||
/** Holds if ESSA edge refinement, `def`, refers to `(value, cls, origin)`. */
|
||||
private predicate ssa_filter_definition_pointsTo(PyEdgeRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
private predicate ssa_filter_definition_points_to(PyEdgeRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
exists(ControlFlowNode test, ControlFlowNode use |
|
||||
refinement_test(test, use, Conditionals::branchEvaluatesTo(test, use, context, value, origin.toCfgNode()), def)
|
||||
)
|
||||
@@ -369,7 +405,7 @@ cached module PointsTo2 {
|
||||
|
||||
/** Holds if ESSA definition, `uniphi`, refers to `(value, origin)`. */
|
||||
pragma [noinline]
|
||||
private predicate uni_edged_phi_pointsTo(SingleSuccessorGuard uniphi, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
private predicate uni_edged_phi_points_to(SingleSuccessorGuard uniphi, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
exists(ControlFlowNode test, ControlFlowNode use |
|
||||
/* Because calls such as `len` may create a new variable, we need to go via the source variable
|
||||
* That is perfectly safe as we are only dealing with calls that do not mutate their arguments.
|
||||
@@ -382,19 +418,19 @@ cached module PointsTo2 {
|
||||
|
||||
/** Points-to for normal assignments `def = ...`. */
|
||||
pragma [noinline]
|
||||
private predicate assignment_pointsTo(AssignmentDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate assignment_points_to(AssignmentDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
pointsTo(def.getValue(), context, value, origin)
|
||||
}
|
||||
|
||||
/** Points-to for deletion: `del name`. */
|
||||
pragma [noinline]
|
||||
private predicate delete_pointsTo(DeletionDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate delete_points_to(DeletionDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
value = ObjectInternal::undefined() and origin = def.getDefiningNode() and context.appliesToScope(def.getScope())
|
||||
}
|
||||
|
||||
/** Implicit "definition" of `__name__` at the start of a module. */
|
||||
pragma [noinline]
|
||||
private predicate module_name_pointsTo(ScopeEntryDefinition def, PointsToContext context, StringObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate module_name_points_to(ScopeEntryDefinition def, PointsToContext context, StringObjectInternal value, ControlFlowNode origin) {
|
||||
def.getVariable().getName() = "__name__" and
|
||||
exists(Module m |
|
||||
m = def.getScope()
|
||||
@@ -418,26 +454,26 @@ cached module PointsTo2 {
|
||||
|
||||
/** Holds if the phi-function `phi` refers to `(value, origin)` given the context `context`. */
|
||||
pragma [nomagic]
|
||||
private predicate ssa_phi_pointsTo(PhiFunction phi, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
private predicate ssa_phi_points_to(PhiFunction phi, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
exists(EssaVariable input, BasicBlock pred |
|
||||
input = phi.getInput(pred) and
|
||||
ssa_variable_pointsTo(input, context, value, origin)
|
||||
variablePointsTo(input, context, value, origin)
|
||||
|
|
||||
controlledReachableEdge(pred, phi.getBasicBlock(), context)
|
||||
or
|
||||
not exists(ConditionBlock guard | guard.controlsEdge(pred, phi.getBasicBlock(), _))
|
||||
)
|
||||
or
|
||||
ssa_variable_pointsTo(phi.getShortCircuitInput(), context, value, origin)
|
||||
variablePointsTo(phi.getShortCircuitInput(), context, value, origin)
|
||||
}
|
||||
|
||||
/** Points-to for implicit variable declarations at scope-entry. */
|
||||
pragma [noinline]
|
||||
private predicate scope_entry_pointsTo(ScopeEntryDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate scope_entry_points_to(ScopeEntryDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
/* Transfer from another scope */
|
||||
exists(EssaVariable var, PointsToContext outer, CfgOrigin orig |
|
||||
InterProceduralPointsTo::scope_entry_value_transfer(var, outer, def, context) and
|
||||
ssa_variable_pointsTo(var, outer, value, orig) and
|
||||
variablePointsTo(var, outer, value, orig) and
|
||||
origin = orig.asCfgNodeOrHere(def.getDefiningNode())
|
||||
)
|
||||
or
|
||||
@@ -462,7 +498,7 @@ cached module PointsTo2 {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate subscript_pointsTo(SubscriptNode sub, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate subscript_points_to(SubscriptNode sub, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
pointsTo(sub.getValue(), context, ObjectInternal::unknown(), _) and
|
||||
value = ObjectInternal::unknown() and origin = sub
|
||||
}
|
||||
@@ -470,21 +506,21 @@ cached module PointsTo2 {
|
||||
/** Track bitwise expressions so we can handle integer flags and enums.
|
||||
* Tracking too many binary expressions is likely to kill performance.
|
||||
*/
|
||||
private predicate binary_expr_pointsTo(BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate binary_expr_points_to(BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
// TO DO...
|
||||
// Track some integer values through `|` and the types of some objects
|
||||
none()
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate compare_expr_pointsTo(CompareNode cmp, PointsToContext context, ObjectInternal value) {
|
||||
private predicate compare_expr_points_to(CompareNode cmp, PointsToContext context, ObjectInternal value) {
|
||||
value = ObjectInternal::bool(Conditionals::comparisonEvaluatesTo(cmp, _, context, _, _))
|
||||
// or
|
||||
// value = version_tuple_compare(cmp, context)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private predicate unary_pointsTo(UnaryExprNode f, PointsToContext context, ObjectInternal value) {
|
||||
private predicate unary_points_to(UnaryExprNode f, PointsToContext context, ObjectInternal value) {
|
||||
exists(Unaryop op, ObjectInternal operand |
|
||||
op = f.getNode().getOp() and
|
||||
pointsTo(f.getOperand(), context, operand, _)
|
||||
@@ -502,7 +538,7 @@ cached module PointsTo2 {
|
||||
module InterModulePointsTo {
|
||||
|
||||
pragma [noinline]
|
||||
predicate import_pointsTo(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
predicate import_points_to(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(string name, ImportExpr i |
|
||||
i.getAFlowNode() = f and i.getImportedModuleName() = name and
|
||||
module_imported_as(value, name) and
|
||||
@@ -511,23 +547,23 @@ module InterModulePointsTo {
|
||||
)
|
||||
}
|
||||
|
||||
predicate from_import_pointsTo(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
from_self_import_pointsTo(f, context, value, origin)
|
||||
predicate from_import_points_to(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
from_self_import_points_to(f, context, value, origin)
|
||||
or
|
||||
from_other_import_pointsTo(f, context, value, origin)
|
||||
from_other_import_points_to(f, context, value, origin)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
predicate from_self_import_pointsTo(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
predicate from_self_import_points_to(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(EssaVariable var, CfgOrigin orig |
|
||||
var = ssa_variable_for_module_attribute(f, context) and
|
||||
PointsTo2::ssa_variable_pointsTo(var, context, value, orig) and
|
||||
PointsToInternal::variablePointsTo(var, context, value, orig) and
|
||||
origin = orig.asCfgNodeOrHere(f)
|
||||
)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
predicate from_other_import_pointsTo(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
predicate from_other_import_points_to(ImportMemberNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(string name, ModuleObjectInternal mod, CfgOrigin orig |
|
||||
from_import_imports(f, context, mod, name) and
|
||||
(mod.getSourceModule() != f.getEnclosingModule() or mod.isBuiltin()) and
|
||||
@@ -538,20 +574,20 @@ module InterModulePointsTo {
|
||||
//not exists(EssaVariable var | var.getSourceVariable().getName() = name and var.getAUse() = f) and
|
||||
//exists(EssaVariable dollar |
|
||||
// isModuleStateVariable(dollar) and dollar.getAUse() = f and
|
||||
// SSA::ssa_variable_named_attribute_pointsTo(dollar, context, name, value, orig)
|
||||
// SSA::ssa_variable_named_attribute_points_to(dollar, context, name, value, orig)
|
||||
//)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate from_import_imports(ImportMemberNode f, PointsToContext context, ModuleObjectInternal mod, string name) {
|
||||
PointsTo2::pointsTo(f.getModule(name), context, mod, _)
|
||||
PointsToInternal::pointsTo(f.getModule(name), context, mod, _)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
private EssaVariable ssa_variable_for_module_attribute(ImportMemberNode f, PointsToContext context) {
|
||||
exists(string name, ModuleObjectInternal mod, Module m |
|
||||
mod.getSourceModule() = m and m = f.getEnclosingModule() and m = result.getScope() and
|
||||
PointsTo2::pointsTo(f.getModule(name), context, mod, _) and
|
||||
PointsToInternal::pointsTo(f.getModule(name), context, mod, _) and
|
||||
result.getSourceVariable().getName() = name and result.getAUse() = f
|
||||
)
|
||||
}
|
||||
@@ -566,11 +602,11 @@ module InterModulePointsTo {
|
||||
/* Use previous points-to here to avoid slowing down the recursion too much */
|
||||
exists(SubscriptNode sub |
|
||||
sub.getValue() = sys_modules_flow and
|
||||
PointsTo2::pointsTo(sys_modules_flow, _, ObjectInternal::sysModules(), _) and
|
||||
PointsToInternal::pointsTo(sys_modules_flow, _, ObjectInternal::sysModules(), _) and
|
||||
sub.getIndex() = n and
|
||||
n.getNode().(StrConst).getText() = name and
|
||||
sub.(DefinitionNode).getValue() = mod and
|
||||
PointsTo2::pointsTo(mod, _, m, _)
|
||||
PointsToInternal::pointsTo(mod, _, m, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -580,7 +616,7 @@ module InterModulePointsTo {
|
||||
* PointsTo isn't exactly how the interpreter works, but is the best approximation we can manage statically.
|
||||
*/
|
||||
pragma [noinline]
|
||||
predicate implicit_submodule_pointsTo(ImplicitSubModuleDefinition def, PointsToContext context, ModuleObjectInternal value, ControlFlowNode origin) {
|
||||
predicate implicit_submodule_points_to(ImplicitSubModuleDefinition def, PointsToContext context, ModuleObjectInternal value, ControlFlowNode origin) {
|
||||
exists(PackageObjectInternal package |
|
||||
package.getSourceModule() = def.getDefiningNode().getScope() |
|
||||
value = package.submodule(def.getSourceVariable().getName()) and
|
||||
@@ -590,12 +626,12 @@ module InterModulePointsTo {
|
||||
}
|
||||
|
||||
/** Points-to for `from ... import *`. */
|
||||
predicate import_star_pointsTo(ImportStarRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
predicate import_star_points_to(ImportStarRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
exists(CfgOrigin orig |
|
||||
origin = orig.fix(def.getDefiningNode())
|
||||
|
|
||||
exists(ModuleObjectInternal mod, string name |
|
||||
PointsTo2::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), context, mod, _) and
|
||||
PointsToInternal::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), context, mod, _) and
|
||||
name = def.getSourceVariable().getName() |
|
||||
/* Attribute from imported module */
|
||||
module_exports_boolean(mod, name) = true and
|
||||
@@ -605,7 +641,7 @@ module InterModulePointsTo {
|
||||
exists(EssaVariable var |
|
||||
/* Retain value held before import */
|
||||
variable_not_redefined_by_import_star(var, context, def) and
|
||||
PointsTo2::ssa_variable_pointsTo(var, context, value,orig)
|
||||
PointsToInternal::variablePointsTo(var, context, value,orig)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -615,7 +651,7 @@ module InterModulePointsTo {
|
||||
cached predicate variable_not_redefined_by_import_star(EssaVariable var, PointsToContext context, ImportStarRefinement def) {
|
||||
var = def.getInput() and
|
||||
exists(ModuleObjectInternal mod |
|
||||
PointsTo2::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), context, mod, _) |
|
||||
PointsToInternal::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), context, mod, _) |
|
||||
module_exports_boolean(mod, var.getSourceVariable().getName()) = false
|
||||
or
|
||||
exists(Module m, string name |
|
||||
@@ -627,7 +663,7 @@ module InterModulePointsTo {
|
||||
|
||||
private predicate importsByImportStar(ModuleObjectInternal mod, ModuleObjectInternal imported) {
|
||||
exists(ImportStarNode isn |
|
||||
PointsTo2::pointsTo(isn.getModule(), _, imported, _) and
|
||||
PointsToInternal::pointsTo(isn.getModule(), _, imported, _) and
|
||||
isn.getScope() = mod.getSourceModule()
|
||||
)
|
||||
or exists(ModuleObjectInternal mid |
|
||||
@@ -660,7 +696,7 @@ module InterModulePointsTo {
|
||||
else (
|
||||
exists(ImportStarNode isn, ModuleObjectInternal imported |
|
||||
isn.getScope() = src and
|
||||
PointsTo2::pointsTo(isn.getModule(), _, imported, _) and
|
||||
PointsToInternal::pointsTo(isn.getModule(), _, imported, _) and
|
||||
result = module_exports_boolean(imported, name)
|
||||
)
|
||||
or
|
||||
@@ -686,9 +722,9 @@ module InterModulePointsTo {
|
||||
module InterProceduralPointsTo {
|
||||
|
||||
pragma [noinline]
|
||||
predicate call_pointsTo(CallNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
predicate call_points_to(CallNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(ObjectInternal func, CfgOrigin resultOrigin |
|
||||
PointsTo2::pointsTo(f.getFunction(), context, func, _) and
|
||||
PointsToInternal::pointsTo(f.getFunction(), context, func, _) and
|
||||
origin = resultOrigin.fix(f)
|
||||
|
|
||||
exists(PointsToContext callee |
|
||||
@@ -702,21 +738,21 @@ module InterProceduralPointsTo {
|
||||
|
||||
/** Points-to for parameter. `def foo(param): ...`. */
|
||||
pragma [noinline]
|
||||
predicate parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
positional_parameter_pointsTo(def, context, value, origin)
|
||||
predicate parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
positional_parameter_points_to(def, context, value, origin)
|
||||
or
|
||||
named_parameter_pointsTo(def, context, value, origin)
|
||||
named_parameter_points_to(def, context, value, origin)
|
||||
or
|
||||
default_parameter_pointsTo(def, context, value, origin)
|
||||
default_parameter_points_to(def, context, value, origin)
|
||||
or
|
||||
special_parameter_pointsTo(def, context, value, origin)
|
||||
special_parameter_points_to(def, context, value, origin)
|
||||
}
|
||||
|
||||
/** Helper for `parameter_pointsTo` */
|
||||
/** Helper for `parameter_points_to` */
|
||||
pragma [noinline]
|
||||
private predicate positional_parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate positional_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(PointsToContext caller, ControlFlowNode arg |
|
||||
PointsTo2::pointsTo(arg, caller, value, origin) and
|
||||
PointsToInternal::pointsTo(arg, caller, value, origin) and
|
||||
callsite_argument_transfer(arg, caller, def, context)
|
||||
)
|
||||
or
|
||||
@@ -725,23 +761,23 @@ module InterProceduralPointsTo {
|
||||
}
|
||||
|
||||
|
||||
/** Helper for `parameter_pointsTo` */
|
||||
/** Helper for `parameter_points_to` */
|
||||
pragma [noinline]
|
||||
private predicate named_parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate named_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(CallNode call, PointsToContext caller, PythonFunctionObjectInternal func, string name |
|
||||
context.fromCall(call, func, caller) and
|
||||
def.getParameter() = func.getScope().getArgByName(name) and
|
||||
PointsTo2::pointsTo(call.getArgByName(name), caller, value, origin)
|
||||
PointsToInternal::pointsTo(call.getArgByName(name), caller, value, origin)
|
||||
)
|
||||
}
|
||||
|
||||
/** Helper for parameter_pointsTo */
|
||||
private predicate default_parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(PointsToContext imp | imp.isImport() | PointsTo2::pointsTo(def.getDefault(), imp, value, origin)) and
|
||||
/** Helper for parameter_points_to */
|
||||
private predicate default_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(PointsToContext imp | imp.isImport() | PointsToInternal::pointsTo(def.getDefault(), imp, value, origin)) and
|
||||
context_for_default_value(def, context)
|
||||
}
|
||||
|
||||
/** Helper for default_parameter_pointsTo */
|
||||
/** Helper for default_parameter_points_to */
|
||||
pragma [noinline]
|
||||
private predicate context_for_default_value(ParameterDefinition def, PointsToContext context) {
|
||||
context.isRuntime()
|
||||
@@ -756,9 +792,9 @@ module InterProceduralPointsTo {
|
||||
)
|
||||
}
|
||||
|
||||
/** Helper for parameter_pointsTo */
|
||||
/** Helper for parameter_points_to */
|
||||
pragma [noinline]
|
||||
private predicate special_parameter_pointsTo(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate special_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
context.isRuntime() and
|
||||
origin = def.getDefiningNode() and
|
||||
exists(ControlFlowNode param |
|
||||
@@ -792,7 +828,7 @@ module InterProceduralPointsTo {
|
||||
cached predicate callsite_calls_function(CallNode call, PointsToContext caller, Function scope, PointsToContext callee, int parameter_offset) {
|
||||
callee.fromCall(call, caller) and
|
||||
exists(ObjectInternal func |
|
||||
PointsTo2::pointsTo(call.getFunction(), caller, func, _) and
|
||||
PointsToInternal::pointsTo(call.getFunction(), caller, func, _) and
|
||||
func.calleeAndOffset(scope, parameter_offset)
|
||||
)
|
||||
}
|
||||
@@ -861,7 +897,7 @@ module InterProceduralPointsTo {
|
||||
* Where var may be redefined in call to `foo` if `var` escapes (is global or non-local).
|
||||
*/
|
||||
pragma [noinline]
|
||||
predicate callsite_pointsTo(CallsiteRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
predicate callsite_points_to(CallsiteRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin) {
|
||||
exists(SsaSourceVariable srcvar |
|
||||
srcvar = def.getSourceVariable() |
|
||||
if srcvar instanceof EscapingAssignmentGlobalVariable then (
|
||||
@@ -869,17 +905,17 @@ module InterProceduralPointsTo {
|
||||
exists(EssaVariable var, Function func, PointsToContext callee |
|
||||
callsite_calls_function(def.getCall(), context, func, callee, _) and
|
||||
var_at_exit(srcvar, func, var) and
|
||||
PointsTo2::ssa_variable_pointsTo(var, callee, value, origin)
|
||||
PointsToInternal::variablePointsTo(var, callee, value, origin)
|
||||
)
|
||||
or
|
||||
exists(ObjectInternal callable |
|
||||
PointsTo2::pointsTo(def.getCall().getFunction(), context, callable, _) and
|
||||
PointsToInternal::pointsTo(def.getCall().getFunction(), context, callable, _) and
|
||||
exists(callable.getBuiltin()) and
|
||||
PointsTo2::ssa_variable_pointsTo(def.getInput(), context, value, origin)
|
||||
PointsToInternal::variablePointsTo(def.getInput(), context, value, origin)
|
||||
)
|
||||
) else (
|
||||
/* Otherwise we can assume its value (but not those of its attributes or members) has not changed. */
|
||||
PointsTo2::ssa_variable_pointsTo(def.getInput(), context, value, origin)
|
||||
PointsToInternal::variablePointsTo(def.getInput(), context, value, origin)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -896,7 +932,7 @@ module InterProceduralPointsTo {
|
||||
|
||||
/** Gets the `value, origin` that `f` would refer to if it has not been assigned some other value */
|
||||
pragma [noinline]
|
||||
private predicate potential_builtin_pointsTo(NameNode f, ObjectInternal value, ControlFlowNode origin) {
|
||||
private predicate potential_builtin_points_to(NameNode f, ObjectInternal value, ControlFlowNode origin) {
|
||||
f.isGlobal() and f.isLoad() and origin = f and
|
||||
(
|
||||
value = ObjectInternal::builtin(f.getId())
|
||||
@@ -915,7 +951,7 @@ private module Conditionals {
|
||||
|
||||
boolean branchEvaluatesTo(ControlFlowNode expr, ControlFlowNode use, PointsToContext context, ObjectInternal val, ControlFlowNode origin) {
|
||||
contains_interesting_expression_within_test(expr, use) and
|
||||
PointsTo2::pointsTo(use, context, val, origin) and
|
||||
PointsToInternal::pointsTo(use, context, val, origin) and
|
||||
expr = use and
|
||||
val.booleanValue() = result
|
||||
or
|
||||
@@ -943,8 +979,8 @@ private module Conditionals {
|
||||
exists(ControlFlowNode r, boolean sense |
|
||||
equality_test(expr, use, sense, r) and
|
||||
exists(ObjectInternal other |
|
||||
PointsTo2::pointsTo(use, context, val, origin) and
|
||||
PointsTo2::pointsTo(r, context, other, _) |
|
||||
PointsToInternal::pointsTo(use, context, val, origin) and
|
||||
PointsToInternal::pointsTo(r, context, other, _) |
|
||||
val.isComparable() = true and other.isComparable() = true and
|
||||
(
|
||||
other = val and result = sense
|
||||
@@ -968,8 +1004,8 @@ private module Conditionals {
|
||||
or
|
||||
inequality(expr, r, use, strict) and sense = false
|
||||
) and
|
||||
PointsTo2::pointsTo(use, context, val, origin) and
|
||||
PointsTo2::pointsTo(r, context, other, _)
|
||||
PointsToInternal::pointsTo(use, context, val, origin) and
|
||||
PointsToInternal::pointsTo(r, context, other, _)
|
||||
|
|
||||
val.intValue() < other.intValue() and result = sense
|
||||
or
|
||||
@@ -1028,7 +1064,7 @@ cached module Types {
|
||||
or
|
||||
exists(Class pycls |
|
||||
pycls = cls.(PythonClassObjectInternal).getScope() |
|
||||
PointsTo2::pointsTo(pycls.getBase(n).getAFlowNode(), _, result, _)
|
||||
PointsToInternal::pointsTo(pycls.getBase(n).getAFlowNode(), _, result, _)
|
||||
or
|
||||
not exists(pycls.getABase()) and n = 0 and
|
||||
isNewStyle(cls) and result = ObjectInternal::builtin("object")
|
||||
@@ -1063,7 +1099,7 @@ cached module Types {
|
||||
exists(EssaVariable var |
|
||||
name = var.getName() and
|
||||
var.getAUse() = cls.(PythonClassObjectInternal).getScope().getANormalExit() and
|
||||
PointsTo2::ssa_variable_pointsTo(var, _, value, origin)
|
||||
PointsToInternal::variablePointsTo(var, _, value, origin)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1075,7 +1111,7 @@ cached module Types {
|
||||
|
||||
private ClassObjectInternal declaredMetaClass(PythonClassObjectInternal cls) {
|
||||
exists(ObjectInternal obj |
|
||||
PointsTo2::ssa_variable_pointsTo(metaclass_var(cls.getScope()), _, obj, _) |
|
||||
PointsToInternal::variablePointsTo(metaclass_var(cls.getScope()), _, obj, _) |
|
||||
result = obj
|
||||
or
|
||||
obj = ObjectInternal::unknown() and result = ObjectInternal::unknownClass()
|
||||
@@ -1083,7 +1119,7 @@ cached module Types {
|
||||
or
|
||||
exists(ControlFlowNode meta |
|
||||
six_add_metaclass(_, cls, meta) and
|
||||
PointsTo2::pointsTo(meta, _, result, _)
|
||||
PointsToInternal::pointsTo(meta, _, result, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1098,7 +1134,7 @@ cached module Types {
|
||||
|
||||
private boolean has_metaclass_var_metaclass(PythonClassObjectInternal cls) {
|
||||
exists(ObjectInternal obj |
|
||||
PointsTo2::ssa_variable_pointsTo(metaclass_var(cls.getScope()), _, obj, _) |
|
||||
PointsToInternal::variablePointsTo(metaclass_var(cls.getScope()), _, obj, _) |
|
||||
obj = ObjectInternal::undefined() and result = false
|
||||
or
|
||||
obj != ObjectInternal::undefined() and result = true
|
||||
@@ -1126,11 +1162,11 @@ cached module Types {
|
||||
// decorator_call.getArg(0) = decorated and
|
||||
// decorator = decorator_call.getFunction() and
|
||||
// decorator.getArg(0) = metaclass |
|
||||
// PointsTo2::pointsTo(decorator.getFunction(), _, six_add_metaclass_function(), _)
|
||||
// PointsToInternal::pointsTo(decorator.getFunction(), _, six_add_metaclass_function(), _)
|
||||
// or
|
||||
// exists(ModuleObjectInternal six |
|
||||
// six.getName() = "six" and
|
||||
// PointsTo2::pointsTo(decorator.getFunction().(AttrNode).getObject("add_metaclass"), _, six, _)
|
||||
// PointsToInternal::pointsTo(decorator.getFunction().(AttrNode).getObject("add_metaclass"), _, six, _)
|
||||
// )
|
||||
//)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
/*
|
||||
* A note on 'cost'. Cost doesn't represent the cost to compute,
|
||||
@@ -149,7 +149,7 @@ class PointsToContext extends TPointsToContext {
|
||||
|
||||
/** Holds if `call` is the call-site from which this context was entered and `caller` is the caller's context. */
|
||||
predicate fromCall(CallNode call, PythonFunctionObjectInternal callee, PointsToContext caller) {
|
||||
call = PointsTo2::get_a_call(callee, caller) and
|
||||
call = callee.getACall(caller) and
|
||||
this = TCallContext(call, caller, _)
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ class PointsToContext extends TPointsToContext {
|
||||
or
|
||||
/* Called functions, regardless of their name */
|
||||
exists(CallableObjectInternal callable, ControlFlowNode call, TPointsToContext outerContext |
|
||||
call = PointsTo2::get_a_call(callable, outerContext) and
|
||||
call = callable.getACall(outerContext) and
|
||||
this = TCallContext(call, outerContext, _) |
|
||||
s = callable.getScope()
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import python
|
||||
private import semmle.python.objects.Classes
|
||||
private import semmle.python.objects.Instances
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.pointsto.MRO2
|
||||
private import semmle.python.types.Builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import python
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import semmle.python.types.Exceptions
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.objects.Callables
|
||||
private import semmle.python.libraries.Zope
|
||||
private import semmle.python.pointsto.Base
|
||||
@@ -64,7 +64,7 @@ abstract class FunctionObject extends Object {
|
||||
|
||||
/** Gets a call-site from where this function is called, given the `context` */
|
||||
ControlFlowNode getACall(Context caller_context) {
|
||||
result = PointsTo2::get_a_call(theCallable(), caller_context)
|
||||
result = theCallable().getACall(caller_context)
|
||||
}
|
||||
|
||||
/** Gets the `ControlFlowNode` that will be passed as the nth argument to `this` when called at `call`.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
private import semmle.python.pointsto.PointsTo2
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.objects.Modules
|
||||
private import semmle.python.types.ModuleKind
|
||||
|
||||
|
||||
Reference in New Issue
Block a user