Python points-to: track instances of int, float or str without a specific value, and calls to bool().

This commit is contained in:
Mark Shannon
2019-07-25 10:24:54 +01:00
parent fc4bb028b7
commit cb719a8998
11 changed files with 160 additions and 11 deletions

View File

@@ -78,6 +78,14 @@ abstract class ConstantObjectInternal extends ObjectInternal {
}
private boolean callToBool(CallNode call, PointsToContext context) {
PointsToInternal::pointsTo(call.getFunction(), context, ClassValue::bool(), _) and
exists(ObjectInternal arg |
PointsToInternal::pointsTo(call.getArg(0),context, arg, _) and
arg.booleanValue() = result
)
}
private abstract class BooleanObjectInternal extends ConstantObjectInternal {
override ObjectInternal getClass() {
@@ -111,6 +119,8 @@ private class TrueObjectInternal extends BooleanObjectInternal, TTrue {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
node.(NameNode).getId() = "True" and context.appliesTo(node)
or
callToBool(node, context) = true
}
override int intValue() {
@@ -135,6 +145,8 @@ private class FalseObjectInternal extends BooleanObjectInternal, TFalse {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
node.(NameNode).getId() = "False" and context.appliesTo(node)
or
callToBool(node, context) = false
}
override int intValue() {

View File

@@ -469,7 +469,7 @@ library class ClassDecl extends @py_object {
result = this.getClass().getName()
}
/** Whether this is a class whose instances we treat specially, rather than as a generic instance.
/** Whether this is a class whose instances must be treated specially, rather than as generic instances.
*/
predicate isSpecial() {
exists(string name |
@@ -478,11 +478,6 @@ library class ClassDecl extends @py_object {
name = "super" or
name = "bool" or
name = "NoneType" or
name = "int" or
name = "long" or
name = "str" or
name = "bytes" or
name = "unicode" or
name = "tuple" or
name = "property" or
name = "ClassMethod" or
@@ -490,8 +485,6 @@ library class ClassDecl extends @py_object {
name = "MethodType" or
name = "ModuleType"
)
or
this = Builtin::builtin("float")
}
/** Holds if for class `C`, `C()` returns an instance of `C` */

View File

@@ -1249,7 +1249,13 @@ module Expressions {
not op instanceof BitOr and
(operand = left or operand = right) and
PointsToInternal::pointsTo(operand, context, opvalue, _) and
value = ObjectInternal::unknown()
(
op instanceof Add and
value = TUnknownInstance(opvalue.getClass())
or
not op instanceof Add and
value = ObjectInternal::unknown()
)
or
op instanceof BitOr and
exists(ObjectInternal lobj, ObjectInternal robj |

View File

@@ -159,6 +159,7 @@
| 106 | ControlFlowNode for inner | Function inner |
| 108 | ControlFlowNode for IntegerLiteral | int 2 |
| 108 | ControlFlowNode for z | int 2 |
| 109 | ControlFlowNode for BinaryExpr | BinaryExpr |
| 109 | ControlFlowNode for y | int 1 |
| 109 | ControlFlowNode for z | int 2 |
| 110 | ControlFlowNode for inner | Function inner |

View File

@@ -159,6 +159,7 @@
| 106 | ControlFlowNode for inner | Function inner | builtin-class function |
| 108 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int |
| 108 | ControlFlowNode for z | int 2 | builtin-class int |
| 109 | ControlFlowNode for BinaryExpr | BinaryExpr | builtin-class int |
| 109 | ControlFlowNode for y | int 1 | builtin-class int |
| 109 | ControlFlowNode for z | int 2 | builtin-class int |
| 110 | ControlFlowNode for inner | Function inner | builtin-class function |

View File

@@ -167,12 +167,10 @@
| c_tests.py:63 | ControlFlowNode for cond | 63 |
| c_tests.py:73 | ControlFlowNode for x | 71 |
| c_tests.py:73 | ControlFlowNode for y | 71 |
| c_tests.py:74 | ControlFlowNode for BinaryExpr | 74 |
| c_tests.py:74 | ControlFlowNode for x | 71 |
| c_tests.py:74 | ControlFlowNode for y | 71 |
| c_tests.py:76 | ControlFlowNode for x | 71 |
| c_tests.py:76 | ControlFlowNode for y | 71 |
| c_tests.py:77 | ControlFlowNode for BinaryExpr | 77 |
| c_tests.py:77 | ControlFlowNode for x | 71 |
| c_tests.py:77 | ControlFlowNode for y | 71 |
| c_tests.py:80 | ControlFlowNode for IfExp | 80 |

View File

@@ -416,6 +416,22 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
| h_classes.py:50 | ControlFlowNode for m | Function f | builtin-class function | 45 | import |
| h_classes.py:52 | ControlFlowNode for FunctionExpr | Function n | builtin-class function | 52 | import |
| h_classes.py:52 | ControlFlowNode for n | Function n | builtin-class function | 52 | import |
| h_classes.py:55 | ControlFlowNode for int | builtin-class int | builtin-class type | 55 | import |
| h_classes.py:55 | ControlFlowNode for int() | int() | builtin-class int | 55 | import |
| h_classes.py:56 | ControlFlowNode for Str | '' | builtin-class str | 56 | import |
| h_classes.py:56 | ControlFlowNode for type | builtin-class type | builtin-class type | 56 | import |
| h_classes.py:56 | ControlFlowNode for type() | builtin-class str | builtin-class type | 56 | import |
| h_classes.py:56 | ControlFlowNode for type()() | type()() | builtin-class str | 56 | import |
| h_classes.py:57 | ControlFlowNode for list | builtin-class list | builtin-class type | 57 | import |
| h_classes.py:57 | ControlFlowNode for list() | list() | builtin-class list | 57 | import |
| h_classes.py:58 | ControlFlowNode for dict | builtin-class dict | builtin-class type | 58 | import |
| h_classes.py:58 | ControlFlowNode for dict() | dict() | builtin-class dict | 58 | import |
| h_classes.py:59 | ControlFlowNode for Str | 'hi' | builtin-class str | 59 | import |
| h_classes.py:59 | ControlFlowNode for bool | builtin-class bool | builtin-class type | 59 | import |
| h_classes.py:59 | ControlFlowNode for bool() | bool True | builtin-class bool | 59 | import |
| h_classes.py:60 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | 60 | import |
| h_classes.py:60 | ControlFlowNode for bool | builtin-class bool | builtin-class type | 60 | import |
| h_classes.py:60 | ControlFlowNode for bool() | bool False | builtin-class bool | 60 | import |
| i_imports.py:3 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 3 | import |
| i_imports.py:3 | ControlFlowNode for a | int 1 | builtin-class int | 3 | import |
| i_imports.py:4 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 4 | import |

View File

@@ -513,6 +513,22 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
| h_classes.py:50 | ControlFlowNode for m | Function f | builtin-class function | 45 |
| h_classes.py:52 | ControlFlowNode for FunctionExpr | Function n | builtin-class function | 52 |
| h_classes.py:52 | ControlFlowNode for n | Function n | builtin-class function | 52 |
| h_classes.py:55 | ControlFlowNode for int | builtin-class int | builtin-class type | 55 |
| h_classes.py:55 | ControlFlowNode for int() | int() | builtin-class int | 55 |
| h_classes.py:56 | ControlFlowNode for Str | '' | builtin-class str | 56 |
| h_classes.py:56 | ControlFlowNode for type | builtin-class type | builtin-class type | 56 |
| h_classes.py:56 | ControlFlowNode for type() | builtin-class str | builtin-class type | 56 |
| h_classes.py:56 | ControlFlowNode for type()() | type()() | builtin-class str | 56 |
| h_classes.py:57 | ControlFlowNode for list | builtin-class list | builtin-class type | 57 |
| h_classes.py:57 | ControlFlowNode for list() | list() | builtin-class list | 57 |
| h_classes.py:58 | ControlFlowNode for dict | builtin-class dict | builtin-class type | 58 |
| h_classes.py:58 | ControlFlowNode for dict() | dict() | builtin-class dict | 58 |
| h_classes.py:59 | ControlFlowNode for Str | 'hi' | builtin-class str | 59 |
| h_classes.py:59 | ControlFlowNode for bool | builtin-class bool | builtin-class type | 59 |
| h_classes.py:59 | ControlFlowNode for bool() | bool True | builtin-class bool | 59 |
| h_classes.py:60 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | 60 |
| h_classes.py:60 | ControlFlowNode for bool | builtin-class bool | builtin-class type | 60 |
| h_classes.py:60 | ControlFlowNode for bool() | bool False | builtin-class bool | 60 |
| i_imports.py:3 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 3 |
| i_imports.py:3 | ControlFlowNode for a | int 1 | builtin-class int | 3 |
| i_imports.py:4 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 4 |

View File

@@ -618,6 +618,90 @@
| h_classes.py:50 | f_2 | ControlFlowNode for f |
| h_classes.py:52 | arg1_0 | Exit node for Function n |
| h_classes.py:52 | self_0 | Exit node for Function n |
| h_classes.py:55 | Base_1 | ControlFlowNode for int() |
| h_classes.py:55 | C_0 | ControlFlowNode for int() |
| h_classes.py:55 | D_1 | ControlFlowNode for int() |
| h_classes.py:55 | Derived1_1 | ControlFlowNode for int() |
| h_classes.py:55 | Derived2_1 | ControlFlowNode for int() |
| h_classes.py:55 | Derived3_1 | ControlFlowNode for int() |
| h_classes.py:55 | __name___0 | ControlFlowNode for int() |
| h_classes.py:55 | __package___0 | ControlFlowNode for int() |
| h_classes.py:55 | f_1 | ControlFlowNode for int() |
| h_classes.py:55 | k_1 | ControlFlowNode for int() |
| h_classes.py:55 | sys_1 | ControlFlowNode for int() |
| h_classes.py:55 | thing_1 | ControlFlowNode for int() |
| h_classes.py:56 | Base_1 | ControlFlowNode for type() |
| h_classes.py:56 | Base_1 | ControlFlowNode for type()() |
| h_classes.py:56 | C_0 | ControlFlowNode for type() |
| h_classes.py:56 | C_0 | ControlFlowNode for type()() |
| h_classes.py:56 | D_1 | ControlFlowNode for type() |
| h_classes.py:56 | D_1 | ControlFlowNode for type()() |
| h_classes.py:56 | Derived1_1 | ControlFlowNode for type() |
| h_classes.py:56 | Derived1_1 | ControlFlowNode for type()() |
| h_classes.py:56 | Derived2_1 | ControlFlowNode for type() |
| h_classes.py:56 | Derived2_1 | ControlFlowNode for type()() |
| h_classes.py:56 | Derived3_1 | ControlFlowNode for type() |
| h_classes.py:56 | Derived3_1 | ControlFlowNode for type()() |
| h_classes.py:56 | __name___0 | ControlFlowNode for type() |
| h_classes.py:56 | __name___0 | ControlFlowNode for type()() |
| h_classes.py:56 | __package___0 | ControlFlowNode for type() |
| h_classes.py:56 | __package___0 | ControlFlowNode for type()() |
| h_classes.py:56 | f_1 | ControlFlowNode for type() |
| h_classes.py:56 | f_1 | ControlFlowNode for type()() |
| h_classes.py:56 | k_1 | ControlFlowNode for type() |
| h_classes.py:56 | k_1 | ControlFlowNode for type()() |
| h_classes.py:56 | sys_1 | ControlFlowNode for type() |
| h_classes.py:56 | sys_1 | ControlFlowNode for type()() |
| h_classes.py:56 | thing_1 | ControlFlowNode for type() |
| h_classes.py:56 | thing_1 | ControlFlowNode for type()() |
| h_classes.py:57 | Base_1 | ControlFlowNode for list() |
| h_classes.py:57 | C_0 | ControlFlowNode for list() |
| h_classes.py:57 | D_1 | ControlFlowNode for list() |
| h_classes.py:57 | Derived1_1 | ControlFlowNode for list() |
| h_classes.py:57 | Derived2_1 | ControlFlowNode for list() |
| h_classes.py:57 | Derived3_1 | ControlFlowNode for list() |
| h_classes.py:57 | __name___0 | ControlFlowNode for list() |
| h_classes.py:57 | __package___0 | ControlFlowNode for list() |
| h_classes.py:57 | f_1 | ControlFlowNode for list() |
| h_classes.py:57 | k_1 | ControlFlowNode for list() |
| h_classes.py:57 | sys_1 | ControlFlowNode for list() |
| h_classes.py:57 | thing_1 | ControlFlowNode for list() |
| h_classes.py:58 | Base_1 | ControlFlowNode for dict() |
| h_classes.py:58 | C_0 | ControlFlowNode for dict() |
| h_classes.py:58 | D_1 | ControlFlowNode for dict() |
| h_classes.py:58 | Derived1_1 | ControlFlowNode for dict() |
| h_classes.py:58 | Derived2_1 | ControlFlowNode for dict() |
| h_classes.py:58 | Derived3_1 | ControlFlowNode for dict() |
| h_classes.py:58 | __name___0 | ControlFlowNode for dict() |
| h_classes.py:58 | __package___0 | ControlFlowNode for dict() |
| h_classes.py:58 | f_1 | ControlFlowNode for dict() |
| h_classes.py:58 | k_1 | ControlFlowNode for dict() |
| h_classes.py:58 | sys_1 | ControlFlowNode for dict() |
| h_classes.py:58 | thing_1 | ControlFlowNode for dict() |
| h_classes.py:59 | Base_1 | ControlFlowNode for bool() |
| h_classes.py:59 | C_0 | ControlFlowNode for bool() |
| h_classes.py:59 | D_1 | ControlFlowNode for bool() |
| h_classes.py:59 | Derived1_1 | ControlFlowNode for bool() |
| h_classes.py:59 | Derived2_1 | ControlFlowNode for bool() |
| h_classes.py:59 | Derived3_1 | ControlFlowNode for bool() |
| h_classes.py:59 | __name___0 | ControlFlowNode for bool() |
| h_classes.py:59 | __package___0 | ControlFlowNode for bool() |
| h_classes.py:59 | f_1 | ControlFlowNode for bool() |
| h_classes.py:59 | k_1 | ControlFlowNode for bool() |
| h_classes.py:59 | sys_1 | ControlFlowNode for bool() |
| h_classes.py:59 | thing_1 | ControlFlowNode for bool() |
| h_classes.py:60 | Base_1 | ControlFlowNode for bool() |
| h_classes.py:60 | C_0 | ControlFlowNode for bool() |
| h_classes.py:60 | D_1 | ControlFlowNode for bool() |
| h_classes.py:60 | Derived1_1 | ControlFlowNode for bool() |
| h_classes.py:60 | Derived2_1 | ControlFlowNode for bool() |
| h_classes.py:60 | Derived3_1 | ControlFlowNode for bool() |
| h_classes.py:60 | __name___0 | ControlFlowNode for bool() |
| h_classes.py:60 | __package___0 | ControlFlowNode for bool() |
| h_classes.py:60 | f_1 | ControlFlowNode for bool() |
| h_classes.py:60 | k_1 | ControlFlowNode for bool() |
| h_classes.py:60 | sys_1 | ControlFlowNode for bool() |
| h_classes.py:60 | thing_1 | ControlFlowNode for bool() |
| j_convoluted_imports.py:0 | C_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __name___3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __package___3 | Exit node for Module code.j_convoluted_imports |

View File

@@ -321,6 +321,22 @@
| h_classes.py:48 | ControlFlowNode for object | import | builtin-class object | builtin-class type |
| h_classes.py:50 | ControlFlowNode for f | import | Function f | builtin-class function |
| h_classes.py:52 | ControlFlowNode for FunctionExpr | import | Function D.n | builtin-class function |
| h_classes.py:55 | ControlFlowNode for int | import | builtin-class int | builtin-class type |
| h_classes.py:55 | ControlFlowNode for int() | import | int() | builtin-class int |
| h_classes.py:56 | ControlFlowNode for Str | import | '' | builtin-class str |
| h_classes.py:56 | ControlFlowNode for type | import | builtin-class type | builtin-class type |
| h_classes.py:56 | ControlFlowNode for type() | import | builtin-class str | builtin-class type |
| h_classes.py:56 | ControlFlowNode for type()() | import | type()() | builtin-class str |
| h_classes.py:57 | ControlFlowNode for list | import | builtin-class list | builtin-class type |
| h_classes.py:57 | ControlFlowNode for list() | import | list() | builtin-class list |
| h_classes.py:58 | ControlFlowNode for dict | import | builtin-class dict | builtin-class type |
| h_classes.py:58 | ControlFlowNode for dict() | import | dict() | builtin-class dict |
| h_classes.py:59 | ControlFlowNode for Str | import | 'hi' | builtin-class str |
| h_classes.py:59 | ControlFlowNode for bool | import | builtin-class bool | builtin-class type |
| h_classes.py:59 | ControlFlowNode for bool() | import | bool True | builtin-class bool |
| h_classes.py:60 | ControlFlowNode for IntegerLiteral | import | int 0 | builtin-class int |
| h_classes.py:60 | ControlFlowNode for bool | import | builtin-class bool | builtin-class type |
| h_classes.py:60 | ControlFlowNode for bool() | import | bool False | builtin-class bool |
| i_imports.py:3 | ControlFlowNode for IntegerLiteral | import | int 1 | builtin-class int |
| i_imports.py:4 | ControlFlowNode for IntegerLiteral | import | int 2 | builtin-class int |
| i_imports.py:5 | ControlFlowNode for IntegerLiteral | import | int 3 | builtin-class int |

View File

@@ -52,3 +52,9 @@ class D(object):
def n(self, arg1):
pass
int()
type("")()
list()
dict()
bool("hi")
bool(0)