Skip to content

Commit bf16e22

Browse files
committed
Python: adjust expectations
1 parent e3280c8 commit bf16e22

File tree

9 files changed

+141
-0
lines changed

9 files changed

+141
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
private import python
2+
private import semmle.python.dataflow.new.FlowSummary
3+
private import semmle.python.ApiGraphs
4+
5+
/** This module ensures that the `callStep` predicate in
6+
* our type tracker implelemtation does not refer to the
7+
* `getACall` predicate on `SummarizedCallable`.
8+
*/
9+
module RecursionGuard {
10+
private import semmle.python.dataflow.new.internal.TypeTrackerSpecific as TT
11+
12+
private class RecursionGuard extends SummarizedCallable {
13+
RecursionGuard() { this = "RecursionGuard" }
14+
15+
override CallNode getACall() {
16+
result.getFunction().(NameNode).getId() = this and
17+
(TT::callStep(_, _) implies any())
18+
}
19+
20+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
21+
}
22+
}
23+
24+
private class SummarizedCallableIdentity extends SummarizedCallable {
25+
SummarizedCallableIdentity() { this = "identity" }
26+
27+
override CallNode getACall() { result.getFunction().(NameNode).getId() = this }
28+
29+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
30+
31+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
32+
input = "Argument[0]" and
33+
output = "ReturnValue" and
34+
preservesValue = true
35+
}
36+
}
37+
38+
// For lambda flow to work, implement lambdaCall and lambdaCreation
39+
private class SummarizedCallableApplyLambda extends SummarizedCallable {
40+
SummarizedCallableApplyLambda() { this = "apply_lambda" }
41+
42+
override CallNode getACall() { result.getFunction().(NameNode).getId() = this }
43+
44+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
45+
46+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
47+
input = "Argument[1]" and
48+
output = "Argument[0].Parameter[0]" and
49+
preservesValue = true
50+
or
51+
input = "Argument[0].ReturnValue" and
52+
output = "ReturnValue" and
53+
preservesValue = true
54+
}
55+
}
56+
57+
private class SummarizedCallableReversed extends SummarizedCallable {
58+
SummarizedCallableReversed() { this = "reversed" }
59+
60+
override CallNode getACall() { result.getFunction().(NameNode).getId() = this }
61+
62+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
63+
64+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
65+
input = "Argument[0].ListElement" and
66+
output = "ReturnValue.ListElement" and
67+
preservesValue = true
68+
}
69+
}
70+
71+
private class SummarizedCallableMap extends SummarizedCallable {
72+
SummarizedCallableMap() { this = "map" }
73+
74+
override CallNode getACall() { result.getFunction().(NameNode).getId() = this }
75+
76+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
77+
78+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
79+
input = "Argument[1].ListElement" and
80+
output = "Argument[0].Parameter[0]" and
81+
preservesValue = true
82+
or
83+
input = "Argument[0].ReturnValue" and
84+
output = "ReturnValue.ListElement" and
85+
preservesValue = true
86+
}
87+
}
88+
89+
private class SummarizedCallableAppend extends SummarizedCallable {
90+
SummarizedCallableAppend() { this = "append_to_list" }
91+
92+
override CallNode getACall() { result.getFunction().(NameNode).getId() = this }
93+
94+
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
95+
96+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
97+
input = "Argument[0]" and
98+
output = "ReturnValue" and
99+
preservesValue = false
100+
or
101+
input = "Argument[1]" and
102+
output = "ReturnValue.ListElement" and
103+
preservesValue = true
104+
}
105+
}
106+
107+
private class SummarizedCallableJsonLoads extends SummarizedCallable {
108+
SummarizedCallableJsonLoads() { this = "json.loads" }
109+
110+
override CallNode getACall() {
111+
result = API::moduleImport("json").getMember("loads").getACall().getNode()
112+
}
113+
114+
override DataFlow::ArgumentNode getACallback() {
115+
result = API::moduleImport("json").getMember("loads").getAValueReachableFromSource()
116+
}
117+
118+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
119+
input = "Argument[0]" and
120+
output = "ReturnValue.ListElement" and
121+
preservesValue = true
122+
}
123+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
| file://:0:0:0:0 | parameter 0 of builtins.reversed |
12
| test.py:1:19:1:19 | ControlFlowNode for x |
23
| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
| file://:0:0:0:0 | [summary] to write: return (return) in builtins.reversed |
12
| test.py:4:10:4:10 | ControlFlowNode for z |
23
| test.py:7:19:7:19 | ControlFlowNode for a |

python/ql/test/experimental/dataflow/basic/global.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
12
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
23
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |
34
| test.py:1:5:1:17 | GSSA Variable obfuscated_id | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |

python/ql/test/experimental/dataflow/basic/globalStep.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
12
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
23
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
34
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |

python/ql/test/experimental/dataflow/basic/local.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed | file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed |
2+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
3+
| file://:0:0:0:0 | [summary] to write: return (return) in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return) in builtins.reversed |
4+
| file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
5+
| file://:0:0:0:0 | parameter 0 of builtins.reversed | file://:0:0:0:0 | parameter 0 of builtins.reversed |
16
| test.py:0:0:0:0 | GSSA Variable __name__ | test.py:0:0:0:0 | GSSA Variable __name__ |
27
| test.py:0:0:0:0 | GSSA Variable __package__ | test.py:0:0:0:0 | GSSA Variable __package__ |
38
| test.py:0:0:0:0 | GSSA Variable b | test.py:0:0:0:0 | GSSA Variable b |

python/ql/test/experimental/dataflow/basic/localStep.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed | file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
12
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
23
| test.py:1:5:1:17 | GSSA Variable obfuscated_id | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |
34
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:1:19:1:19 | SSA variable x |

python/ql/test/experimental/dataflow/basic/sinks.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed |
2+
| file://:0:0:0:0 | [summary] to write: return (return) in builtins.reversed |
3+
| file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
4+
| file://:0:0:0:0 | parameter 0 of builtins.reversed |
15
| test.py:0:0:0:0 | GSSA Variable __name__ |
26
| test.py:0:0:0:0 | GSSA Variable __package__ |
37
| test.py:0:0:0:0 | GSSA Variable b |

python/ql/test/experimental/dataflow/basic/sources.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
| file://:0:0:0:0 | [summary] read: argument 0.List element in builtins.reversed |
2+
| file://:0:0:0:0 | [summary] to write: return (return) in builtins.reversed |
3+
| file://:0:0:0:0 | [summary] to write: return (return).List element in builtins.reversed |
4+
| file://:0:0:0:0 | parameter 0 of builtins.reversed |
15
| test.py:0:0:0:0 | GSSA Variable __name__ |
26
| test.py:0:0:0:0 | GSSA Variable __package__ |
37
| test.py:0:0:0:0 | GSSA Variable b |

0 commit comments

Comments
 (0)