diff --git a/python/ql/src/semmle/python/pointsto/Base.qll b/python/ql/src/semmle/python/pointsto/Base.qll index 0562b9fcda7a..7dfc068250e5 100644 --- a/python/ql/src/semmle/python/pointsto/Base.qll +++ b/python/ql/src/semmle/python/pointsto/Base.qll @@ -50,6 +50,8 @@ ClassObject simple_types(Object obj) { obj.getOrigin() instanceof Module and result = theModuleType() or result = builtin_object_type(obj) + or + obj = unknownValue() and result = theUnknownType() } private ClassObject comprehension(Expr e) { diff --git a/python/ql/src/semmle/python/types/Extensions.qll b/python/ql/src/semmle/python/types/Extensions.qll index 56fc44b076d9..9046320e9ec4 100644 --- a/python/ql/src/semmle/python/types/Extensions.qll +++ b/python/ql/src/semmle/python/types/Extensions.qll @@ -3,6 +3,10 @@ * * This should be considered an advance feature. Modifying the points-to analysis * can cause queries to give strange and misleading results, if not done with care. + * + * WARNING: + * This module interacts with the internals of points-to analysis and + * the classes here are more likely to change than the rest of the library. */ import python @@ -34,6 +38,18 @@ abstract class CustomPointsToOriginFact extends CustomPointsToFact { } +/* Custom points-to fact with inferred class */ +abstract class CustomPointsToObjectFact extends CustomPointsToFact { + + abstract predicate pointsTo(Object value); + + override predicate pointsTo(Context context, Object value, ClassObject cls, ControlFlowNode origin) { + this.pointsTo(value) and cls = simple_types(value) and origin = this and context.appliesTo(this) + } + +} + + /** INTERNAL -- Do not use */ abstract class CustomPointsToAttribute extends Object { diff --git a/python/ql/test/library-tests/PointsTo/extensions/Extend.expected b/python/ql/test/library-tests/PointsTo/extensions/Extend.expected index 1052ac9bbc6b..1cb63564722b 100644 --- a/python/ql/test/library-tests/PointsTo/extensions/Extend.expected +++ b/python/ql/test/library-tests/PointsTo/extensions/Extend.expected @@ -1,10 +1,12 @@ | test.py:4:1:4:3 | ControlFlowNode for one | int 1 | | test.py:5:1:5:3 | ControlFlowNode for two | int 2 | | test.py:8:1:8:1 | ControlFlowNode for IntegerLiteral | int 1 | -| test.py:8:1:8:7 | ControlFlowNode for Tuple | Tuple | +| test.py:8:1:8:11 | ControlFlowNode for Tuple | Tuple | | test.py:8:3:8:3 | ControlFlowNode for IntegerLiteral | int 2 | | test.py:8:5:8:5 | ControlFlowNode for IntegerLiteral | int 3 | | test.py:8:7:8:7 | ControlFlowNode for IntegerLiteral | int 4 | +| test.py:8:9:8:9 | ControlFlowNode for IntegerLiteral | int 5 | +| test.py:8:11:8:11 | ControlFlowNode for IntegerLiteral | int 6 | | test.py:10:1:10:2 | ControlFlowNode for a3 | int 3 | | test.py:10:6:10:7 | ControlFlowNode for Tuple | Tuple | | test.py:10:6:10:13 | ControlFlowNode for Attribute | int 3 | @@ -13,3 +15,5 @@ | test.py:11:6:11:15 | ControlFlowNode for Attribute | int 4 | | test.py:13:1:13:2 | ControlFlowNode for a3 | int 3 | | test.py:14:1:14:2 | ControlFlowNode for a4 | int 4 | +| test.py:16:1:16:4 | ControlFlowNode for five | int 5 | +| test.py:17:1:17:3 | ControlFlowNode for six | int 6 | diff --git a/python/ql/test/library-tests/PointsTo/extensions/Extend.ql b/python/ql/test/library-tests/PointsTo/extensions/Extend.ql index d5710a7762a1..b947bd0a900b 100644 --- a/python/ql/test/library-tests/PointsTo/extensions/Extend.ql +++ b/python/ql/test/library-tests/PointsTo/extensions/Extend.ql @@ -38,6 +38,19 @@ class AttributeExtension extends CustomPointsToAttribute { } +class NoClassExtension extends CustomPointsToObjectFact { + + NoClassExtension() { this = this } + + override predicate pointsTo(Object value) { + this.(NameNode).getId() = "five" and value.(NumericObject).intValue() = 5 + or + this.(NameNode).getId() = "six" and value.(NumericObject).intValue() = 6 + } + +} + + from ControlFlowNode f, Object o where f.getLocation().getFile().getBaseName() = "test.py" and f.refersTo(o) select f, o.toString() diff --git a/python/ql/test/library-tests/PointsTo/extensions/test.py b/python/ql/test/library-tests/PointsTo/extensions/test.py index b7d375688d77..7422cce15d24 100644 --- a/python/ql/test/library-tests/PointsTo/extensions/test.py +++ b/python/ql/test/library-tests/PointsTo/extensions/test.py @@ -5,10 +5,13 @@ two #Make sure values exist in DB -1,2,3,4 +1,2,3,4,5,6 a3 = ().three a4 = False.four a3 a4 + +five +six