Skip to content

Commit 6bc159c

Browse files
committed
Python: Remove points-to from Expr
1 parent 4470bfe commit 6bc159c

35 files changed

+162
-119
lines changed

python/ql/examples/snippets/builtin_object.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
*/
99

1010
import python
11+
private import LegacyPointsTo
1112

12-
from Expr e, string name
13+
from ExprWithPointsTo e, string name
1314
where e.pointsTo(Value::named(name)) and not name.charAt(_) = "."
1415
select e

python/ql/examples/snippets/catch_exception.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
*/
99

1010
import python
11+
private import LegacyPointsTo
1112

1213
from ExceptStmt ex, ClassValue cls
1314
where
1415
cls.getName() = "MyExceptionClass" and
15-
ex.getType().pointsTo(cls)
16+
ex.getType().(ExprWithPointsTo).pointsTo(cls)
1617
select ex

python/ql/examples/snippets/conditional_expression.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
*/
1010

1111
import python
12+
private import LegacyPointsTo
1213

1314
from IfExp e, ClassObject cls1, ClassObject cls2
1415
where
15-
e.getBody().refersTo(_, cls1, _) and
16-
e.getOrelse().refersTo(_, cls2, _) and
16+
e.getBody().(ExprWithPointsTo).refersTo(_, cls1, _) and
17+
e.getOrelse().(ExprWithPointsTo).refersTo(_, cls2, _) and
1718
cls1 != cls2
1819
select e

python/ql/examples/snippets/new_instance.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
*/
99

1010
import python
11+
private import LegacyPointsTo
1112

1213
from Call new, ClassValue cls
1314
where
1415
cls.getName() = "MyClass" and
15-
new.getFunc().pointsTo(cls)
16+
new.getFunc().(ExprWithPointsTo).pointsTo(cls)
1617
select new

python/ql/examples/snippets/print.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
*/
77

88
import python
9+
private import LegacyPointsTo
910

1011
from AstNode print
1112
where
1213
/* Python 2 without `from __future__ import print_function` */
1314
print instanceof Print
1415
or
1516
/* Python 3 or with `from __future__ import print_function` */
16-
print.(Call).getFunc().pointsTo(Value::named("print"))
17+
print.(Call).getFunc().(ExprWithPointsTo).pointsTo(Value::named("print"))
1718
select print

python/ql/examples/snippets/raise_exception.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
*/
99

1010
import python
11+
private import LegacyPointsTo
1112

1213
from Raise raise, ClassValue ex
1314
where
1415
ex.getName() = "AnException" and
15-
raise.getException().pointsTo(ex.getASuperType())
16+
raise.getException().(ExprWithPointsTo).pointsTo(ex.getASuperType())
1617
select raise, "Don't raise instances of 'AnException'"

python/ql/lib/LegacyPointsTo.qll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,73 @@ private predicate varHasCompletePointsToSet(SsaVariable var) {
119119
)
120120
)
121121
}
122+
123+
/**
124+
* An extension of `Expr` that provides points-to predicates.
125+
*/
126+
class ExprWithPointsTo extends Expr {
127+
/**
128+
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
129+
* Gets what this expression might "refer-to". Performs a combination of localized (intra-procedural) points-to
130+
* analysis and global module-level analysis. This points-to analysis favours precision over recall. It is highly
131+
* precise, but may not provide information for a significant number of flow-nodes.
132+
* If the class is unimportant then use `refersTo(value)` or `refersTo(value, origin)` instead.
133+
* NOTE: For complex dataflow, involving multiple stages of points-to analysis, it may be more precise to use
134+
* `ControlFlowNode.refersTo(...)` instead.
135+
*/
136+
predicate refersTo(Object obj, ClassObject cls, AstNode origin) {
137+
this.refersTo(_, obj, cls, origin)
138+
}
139+
140+
/**
141+
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
142+
* Gets what this expression might "refer-to" in the given `context`.
143+
*/
144+
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
145+
this.getAFlowNode()
146+
.(ControlFlowNodeWithPointsTo)
147+
.refersTo(context, obj, cls, origin.getAFlowNode())
148+
}
149+
150+
/**
151+
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
152+
* Holds if this expression might "refer-to" to `value` which is from `origin`
153+
* Unlike `this.refersTo(value, _, origin)`, this predicate includes results
154+
* where the class cannot be inferred.
155+
*/
156+
pragma[nomagic]
157+
predicate refersTo(Object obj, AstNode origin) {
158+
this.getAFlowNode().(ControlFlowNodeWithPointsTo).refersTo(obj, origin.getAFlowNode())
159+
}
160+
161+
/**
162+
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
163+
* Equivalent to `this.refersTo(value, _)`
164+
*/
165+
predicate refersTo(Object obj) { this.refersTo(obj, _) }
166+
167+
/**
168+
* Holds if this expression might "point-to" to `value` which is from `origin`
169+
* in the given `context`.
170+
*/
171+
predicate pointsTo(Context context, Value value, AstNode origin) {
172+
this.getAFlowNode()
173+
.(ControlFlowNodeWithPointsTo)
174+
.pointsTo(context, value, origin.getAFlowNode())
175+
}
176+
177+
/**
178+
* Holds if this expression might "point-to" to `value` which is from `origin`.
179+
*/
180+
predicate pointsTo(Value value, AstNode origin) {
181+
this.getAFlowNode().(ControlFlowNodeWithPointsTo).pointsTo(value, origin.getAFlowNode())
182+
}
183+
184+
/**
185+
* Holds if this expression might "point-to" to `value`.
186+
*/
187+
predicate pointsTo(Value value) { this.pointsTo(value, _) }
188+
189+
/** Gets a value that this expression might "point-to". */
190+
Value pointsTo() { this.pointsTo(result) }
191+
}

python/ql/lib/semmle/python/Exprs.qll

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import python
2-
private import LegacyPointsTo
3-
private import semmle.python.pointsto.PointsTo
4-
private import semmle.python.objects.ObjectInternal
1+
private import python
52
private import semmle.python.internal.CachedStages
63

74
/** An expression */
@@ -53,71 +50,6 @@ class Expr extends Expr_, AstNode {
5350
Expr getASubExpression() { none() }
5451

5552
override AstNode getAChildNode() { result = this.getASubExpression() }
56-
57-
/**
58-
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
59-
* Gets what this expression might "refer-to". Performs a combination of localized (intra-procedural) points-to
60-
* analysis and global module-level analysis. This points-to analysis favours precision over recall. It is highly
61-
* precise, but may not provide information for a significant number of flow-nodes.
62-
* If the class is unimportant then use `refersTo(value)` or `refersTo(value, origin)` instead.
63-
* NOTE: For complex dataflow, involving multiple stages of points-to analysis, it may be more precise to use
64-
* `ControlFlowNode.refersTo(...)` instead.
65-
*/
66-
predicate refersTo(Object obj, ClassObject cls, AstNode origin) {
67-
this.refersTo(_, obj, cls, origin)
68-
}
69-
70-
/**
71-
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
72-
* Gets what this expression might "refer-to" in the given `context`.
73-
*/
74-
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
75-
this.getAFlowNode()
76-
.(ControlFlowNodeWithPointsTo)
77-
.refersTo(context, obj, cls, origin.getAFlowNode())
78-
}
79-
80-
/**
81-
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
82-
* Holds if this expression might "refer-to" to `value` which is from `origin`
83-
* Unlike `this.refersTo(value, _, origin)`, this predicate includes results
84-
* where the class cannot be inferred.
85-
*/
86-
pragma[nomagic]
87-
predicate refersTo(Object obj, AstNode origin) {
88-
this.getAFlowNode().(ControlFlowNodeWithPointsTo).refersTo(obj, origin.getAFlowNode())
89-
}
90-
91-
/**
92-
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
93-
* Equivalent to `this.refersTo(value, _)`
94-
*/
95-
predicate refersTo(Object obj) { this.refersTo(obj, _) }
96-
97-
/**
98-
* Holds if this expression might "point-to" to `value` which is from `origin`
99-
* in the given `context`.
100-
*/
101-
predicate pointsTo(Context context, Value value, AstNode origin) {
102-
this.getAFlowNode()
103-
.(ControlFlowNodeWithPointsTo)
104-
.pointsTo(context, value, origin.getAFlowNode())
105-
}
106-
107-
/**
108-
* Holds if this expression might "point-to" to `value` which is from `origin`.
109-
*/
110-
predicate pointsTo(Value value, AstNode origin) {
111-
this.getAFlowNode().(ControlFlowNodeWithPointsTo).pointsTo(value, origin.getAFlowNode())
112-
}
113-
114-
/**
115-
* Holds if this expression might "point-to" to `value`.
116-
*/
117-
predicate pointsTo(Value value) { this.pointsTo(value, _) }
118-
119-
/** Gets a value that this expression might "point-to". */
120-
Value pointsTo() { this.pointsTo(result) }
12153
}
12254

12355
/** An assignment expression, such as `x := y` */

python/ql/lib/semmle/python/Metrics.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class ClassMetrics extends Class {
124124
)
125125
or
126126
exists(Function f, Call c, ClassObject cls | c.getScope() = f and f.getScope() = this |
127-
c.getFunc().refersTo(cls) and
127+
c.getFunc().(ExprWithPointsTo).refersTo(cls) and
128128
cls.getPyClass() = other
129129
)
130130
)
@@ -293,7 +293,7 @@ class ModuleMetrics extends Module {
293293
)
294294
or
295295
exists(Function f, Call c, ClassObject cls | c.getScope() = f and f.getScope() = this |
296-
c.getFunc().refersTo(cls) and
296+
c.getFunc().(ExprWithPointsTo).refersTo(cls) and
297297
cls.getPyClass().getEnclosingModule() = other
298298
)
299299
)

python/ql/lib/semmle/python/objects/ObjectAPI.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,9 @@ abstract class FunctionValue extends CallableValue {
697697
exists(ClassValue cls, string name |
698698
cls.declaredAttribute(name) = this and
699699
name != "__new__" and
700-
exists(Expr expr, AstNode origin | expr.pointsTo(this, origin) | not origin instanceof Lambda)
700+
exists(ExprWithPointsTo expr, AstNode origin | expr.pointsTo(this, origin) |
701+
not origin instanceof Lambda
702+
)
701703
)
702704
}
703705

0 commit comments

Comments
 (0)