From a5fbbdeaf137be3863df71e7aaa089c9af2cf507 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 14 Jun 2019 16:16:06 +0100 Subject: [PATCH] Python: Minor performance enhancements. --- python/ql/src/semmle/python/objects/Instances.qll | 9 +++++++-- python/ql/src/semmle/python/pointsto/PointsTo.qll | 14 +++++++++++--- .../src/semmle/python/pointsto/PointsToContext.qll | 2 +- .../src/semmle/python/security/TaintTracking.qll | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/python/ql/src/semmle/python/objects/Instances.qll b/python/ql/src/semmle/python/objects/Instances.qll index 43811c27d426..b2dc7eb07d05 100644 --- a/python/ql/src/semmle/python/objects/Instances.qll +++ b/python/ql/src/semmle/python/objects/Instances.qll @@ -440,9 +440,8 @@ class SuperInstance extends TSuperInstance, ObjectInternal { pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() } pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { - PointsToInternal::attributeRequired(this, name) and exists(ObjectInternal cls_attr, CfgOrigin attr_orig | - this.lookup(name, cls_attr, attr_orig) + this.attribute_descriptor(name, cls_attr, attr_orig) | cls_attr.isDescriptor() = false and value = cls_attr and origin = attr_orig or @@ -450,6 +449,12 @@ class SuperInstance extends TSuperInstance, ObjectInternal { ) } + /* Helper for `attribute` */ + pragma [noinline] private predicate attribute_descriptor(string name, ObjectInternal cls_attr, CfgOrigin attr_orig) { + PointsToInternal::attributeRequired(this, name) and + this.lookup(name, cls_attr, attr_orig) + } + private predicate lookup(string name, ObjectInternal value, CfgOrigin origin) { Types::getMro(this.getSelf().getClass()).startingAt(this.getStartClass()).getTail().lookup(name, value, origin) } diff --git a/python/ql/src/semmle/python/pointsto/PointsTo.qll b/python/ql/src/semmle/python/pointsto/PointsTo.qll index ca6d4f3a320b..87923ed4828d 100644 --- a/python/ql/src/semmle/python/pointsto/PointsTo.qll +++ b/python/ql/src/semmle/python/pointsto/PointsTo.qll @@ -1856,9 +1856,13 @@ cached module Types { result = getInheritedMetaclass(cls, 0) or // Best guess if base is not a known class + hasUnknownBase(cls) and result = ObjectInternal::unknownClass() + } + + /* Helper for getInheritedMetaclass */ + private predicate hasUnknownBase(ClassObjectInternal cls) { exists(ObjectInternal base | - base = getBase(cls, _) and - result = ObjectInternal::unknownClass() | + base = getBase(cls, _) | base.isClass() = false or base = ObjectInternal::unknownClass() @@ -1868,14 +1872,18 @@ cached module Types { private ClassObjectInternal getInheritedMetaclass(ClassObjectInternal cls, int n) { exists(Class c | c = cls.(PythonClassObjectInternal).getScope() and - n = count(c.getABase()) + n = count(c.getABase()) and n != 1 | result = ObjectInternal::type() and major_version() = 3 or result = ObjectInternal::classType() and major_version() = 2 ) or + base_count(cls) = 1 and n = 0 and + result = getBase(cls, 0).getClass() + or exists(ClassObjectInternal meta1, ClassObjectInternal meta2 | + base_count(cls) > 1 and meta1 = getBase(cls, n).getClass() and meta2 = getInheritedMetaclass(cls, n+1) | diff --git a/python/ql/src/semmle/python/pointsto/PointsToContext.qll b/python/ql/src/semmle/python/pointsto/PointsToContext.qll index d2dfdd9dccf0..eb681bca00ee 100644 --- a/python/ql/src/semmle/python/pointsto/PointsToContext.qll +++ b/python/ql/src/semmle/python/pointsto/PointsToContext.qll @@ -182,7 +182,7 @@ class PointsToContext extends TPointsToContext { this = TRuntimeContext() and executes_in_runtime_context(s) or /* Called functions, regardless of their name */ - exists(CallableObjectInternal callable, ControlFlowNode call, TPointsToContext outerContext | + exists(PythonFunctionObjectInternal callable, ControlFlowNode call, TPointsToContext outerContext | call = callable.getACall(outerContext) and this = TCallContext(call, outerContext, _) | s = callable.getScope() diff --git a/python/ql/src/semmle/python/security/TaintTracking.qll b/python/ql/src/semmle/python/security/TaintTracking.qll index 9e94c3546671..3c90b8eac397 100755 --- a/python/ql/src/semmle/python/security/TaintTracking.qll +++ b/python/ql/src/semmle/python/security/TaintTracking.qll @@ -1512,7 +1512,7 @@ class CallContext extends TCallContext { f.getFunction() = s and f.getACall() = call ) or - exists(ClassValue cls,CallNode call | + exists(ClassValue cls, CallNode call | this = TCalleeContext(call, _, _) and call.getFunction().pointsTo(cls) and s = cls.lookup("__init__").(CallableValue).getScope() and