Python points-to: Remove negative recursion when using legacy points-to in legacy points-to extensions.

This commit is contained in:
Mark Shannon
2019-07-18 12:23:36 +01:00
parent 3f464926a2
commit 54a8c64b23
17 changed files with 77 additions and 31 deletions

View File

@@ -156,6 +156,8 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
function = this and offset = 0
}
override predicate useOriginAsLegacyObject() { none() }
}
@@ -277,6 +279,8 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
function = this and offset = 0
}
override predicate useOriginAsLegacyObject() { none() }
}
/** Class representing methods of built-in classes (otherwise known as method-descriptors) such as `list.append`.
@@ -367,6 +371,8 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
function = this and offset = 0
}
override predicate useOriginAsLegacyObject() { none() }
}
/** Class representing bound-methods.
@@ -453,6 +459,8 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
function = this.getFunction() and offset = 1
}
override predicate useOriginAsLegacyObject() { any() }
}

View File

@@ -89,6 +89,9 @@ abstract class ClassObjectInternal extends ObjectInternal {
}
override predicate subscriptUnknown() { none() }
override predicate useOriginAsLegacyObject() { none() }
}
/** Class representing Python source classes */

View File

@@ -69,6 +69,8 @@ abstract class ConstantObjectInternal extends ObjectInternal {
override string getName() { none() }
override predicate useOriginAsLegacyObject() { none() }
}
private abstract class BooleanObjectInternal extends ConstantObjectInternal {

View File

@@ -91,6 +91,7 @@ class PropertyInternal extends ObjectInternal, TProperty {
)
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A class representing classmethods in Python */
@@ -176,6 +177,8 @@ class ClassMethodObjectInternal extends ObjectInternal, TClassMethod {
result = this.getFunction().getName()
}
override predicate useOriginAsLegacyObject() { none() }
}
class StaticMethodObjectInternal extends ObjectInternal, TStaticMethod {
@@ -247,4 +250,6 @@ class StaticMethodObjectInternal extends ObjectInternal, TStaticMethod {
result = this.getFunction().getName()
}
override predicate useOriginAsLegacyObject() { none() }
}

View File

@@ -160,6 +160,8 @@ class SpecificInstanceInternal extends TSpecificInstance, InstanceObject {
)
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A class representing context-free instances represented by `self` in the source code
@@ -262,6 +264,8 @@ class SelfInstanceInternal extends TSelfInstance, InstanceObject {
this.getClass().attribute("__init__", init, _)
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A class representing a value that has a known class, but no other information */
@@ -366,6 +370,8 @@ class UnknownInstanceInternal extends TUnknownInstance, ObjectInternal {
override string getName() { none() }
override predicate useOriginAsLegacyObject() { any() }
}
private int lengthFromClass(ClassObjectInternal cls) {
@@ -472,5 +478,7 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
override string getName() { none() }
override predicate useOriginAsLegacyObject() { any() }
}

View File

@@ -52,6 +52,8 @@ abstract class ModuleObjectInternal extends ObjectInternal {
any(PackageObjectInternal package).getInitModule() = this
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A class representing built-in modules */
@@ -308,10 +310,6 @@ class AbsentModuleObjectInternal extends ModuleObjectInternal, TAbsentModule {
none()
}
override predicate isMissing() {
any()
}
}
/** A class representing an attribute of a missing module. */
@@ -397,12 +395,10 @@ class AbsentModuleAttributeObjectInternal extends ObjectInternal, TAbsentModuleA
override predicate subscriptUnknown() { any() }
override predicate isMissing() {
any()
}
/* We know what this is called, but not its innate name */
override string getName() { none() }
override predicate useOriginAsLegacyObject() { none() }
}

View File

@@ -78,14 +78,6 @@ class Value extends TObject {
this.(ObjectInternal).isBuiltin()
}
/** Holds if this value represents an entity that is inferred to exist,
* but missing from the database.
* Most commonly, this is a module that is imported, but wasn't present during extraction.
*/
predicate isMissing() {
this.(ObjectInternal).isMissing()
}
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
this.(ObjectInternal).getOrigin().getLocation().hasLocationInfo(filepath, bl, bc, el, ec)
or

View File

@@ -155,11 +155,12 @@ class ObjectInternal extends TObject {
*/
predicate functionAndOffset(CallableObjectInternal function, int offset) { none() }
/** Holds if this 'object' represents an entity that is inferred to exist
* but is missing from the database */
predicate isMissing() {
none()
}
/** Holds if this 'object' represents an entity that should be exposed to the legacy points_to API
* This should hold for almost objects that do not have an underlying DB object representing their source,
* for example `super` objects and bound-method. This should not hold for objects that are inferred to exists by
* an import statements or the like, but which aren't in the database. */
/* This predicate can be removed when the legacy points_to API is removed. */
abstract predicate useOriginAsLegacyObject();
/** Gets the name of this of this object if it has a meaningful name.
* Note that the name of an object is not necessarily the name by which it is called
@@ -249,6 +250,9 @@ class BuiltinOpaqueObjectInternal extends ObjectInternal, TBuiltinOpaqueObject {
override string getName() {
result = this.getBuiltin().getName()
}
override predicate useOriginAsLegacyObject() { none() }
}
@@ -326,6 +330,8 @@ class UnknownInternal extends ObjectInternal, TUnknown {
override string getName() { none() }
override predicate useOriginAsLegacyObject() { none() }
}
class UndefinedInternal extends ObjectInternal, TUndefined {
@@ -404,6 +410,8 @@ class UndefinedInternal extends ObjectInternal, TUndefined {
override string getName() { none() }
override predicate useOriginAsLegacyObject() { none() }
}
module ObjectInternal {
@@ -498,6 +506,7 @@ module ObjectInternal {
result.(BuiltinTupleObjectInternal).length() = 0
}
}
/** Helper for boolean predicates returning both `true` and `false` */

View File

@@ -117,6 +117,9 @@ class BuiltinTupleObjectInternal extends TBuiltinTuple, TupleObjectInternal {
result = count(int n | exists(b.getItem(n)))
)
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A tuple declared by a tuple expression in the Python source code */
@@ -148,6 +151,8 @@ class PythonTupleObjectInternal extends TPythonTuple, TupleObjectInternal {
)
}
override predicate useOriginAsLegacyObject() { none() }
}
/** A tuple created by a `*` parameter */
@@ -176,6 +181,9 @@ class VarargsTupleObjectInternal extends TVarargsTuple, TupleObjectInternal {
override int length() {
this = TVarargsTuple(_, _, _, result)
}
override predicate useOriginAsLegacyObject() { any() }
}
@@ -256,4 +264,6 @@ class SysVersionInfoObjectInternal extends TSysVersionInfo, SequenceObjectIntern
override predicate functionAndOffset(CallableObjectInternal function, int offset) { none() }
override predicate useOriginAsLegacyObject() { any() }
}

View File

@@ -130,7 +130,7 @@ module PointsTo {
PointsToInternal::pointsTo(f, context, value, origin) and
cls = value.getClass().getSource() |
obj = value.getSource() or
not exists(value.getSource()) and not value.isMissing() and obj = origin
value.useOriginAsLegacyObject() and obj = origin
)
or
/* Backwards compatibility for *args and **kwargs */
@@ -145,7 +145,7 @@ module PointsTo {
PointsToInternal::pointsTo(f.(DefinitionNode).getValue(), context, value, origin) and
cls = value.getClass().getSource() |
obj = value.getSource() or
not exists(value.getSource()) and obj = origin
value.useOriginAsLegacyObject() and obj = origin
)
}

View File

@@ -13,9 +13,11 @@ import python
private import semmle.python.pointsto.PointsTo
private import semmle.python.pointsto.PointsToContext
private import semmle.python.objects.TObject
private import semmle.python.objects.ObjectInternal
private import semmle.python.web.HttpConstants
/* Make ObjectInternal visible to save extra imports in user code */
import semmle.python.objects.ObjectInternal
abstract class PointsToExtension extends @py_flow_node {
string toString() { none() }