Skip to content

Commit 43b0250

Browse files
committed
Python: Avoid overlap between AssignmentDefinition and ParameterDefinition
1 parent 4e8a114 commit 43b0250

File tree

7 files changed

+25
-67
lines changed

7 files changed

+25
-67
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,7 @@ module EssaFlow {
292292
// nodeFrom is `f(42)`, cfg node
293293
// nodeTo is `x`, essa var
294294
nodeFrom.(CfgNode).getNode() =
295-
nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() and
296-
// we need to ensure that enclosing callable is the same, since a parameter with a
297-
// default value will be in the scope of the function, while the default value
298-
// itself will be in the scope that _defines_ the function.
299-
// We handle _that_ as a jumpstep
300-
nodeFrom.getEnclosingCallable() = nodeTo.getEnclosingCallable()
295+
nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue()
301296
or
302297
// With definition
303298
// `with f(42) as x:`
@@ -473,8 +468,7 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) {
473468
// function, while the default value itself will be in the scope that _defines_ the
474469
// function.
475470
nodeFrom.(CfgNode).getNode() =
476-
nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() and
477-
not nodeFrom.getEnclosingCallable() = nodeTo.getEnclosingCallable()
471+
nodeTo.(EssaNode).getVar().getDefinition().(ParameterDefinition).getDefault()
478472
}
479473

480474
/**

python/ql/lib/semmle/python/essa/Essa.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ class AssignmentDefinition extends EssaNodeDefinition {
501501
ControlFlowNode value;
502502

503503
AssignmentDefinition() {
504-
SsaSource::assignment_definition(this.getSourceVariable(), this.getDefiningNode(), value)
504+
SsaSource::assignment_definition(this.getSourceVariable(), this.getDefiningNode(), value) and
505+
not this instanceof ParameterDefinition
505506
}
506507

507508
ControlFlowNode getValue() { result = value }
Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +0,0 @@
1-
| AssignmentDefinition | a at code/m_attributes.py:5 | has non-disjoint subclasses |
2-
| AssignmentDefinition | b at code/a_simple.py:38 | has non-disjoint subclasses |
3-
| AssignmentDefinition | c at code/a_simple.py:38 | has non-disjoint subclasses |
4-
| AssignmentDefinition | compile_ops at code/n_nesting.py:8 | has non-disjoint subclasses |
5-
| AssignmentDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/_py_abc.py:72 | has non-disjoint subclasses |
6-
| AssignmentDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/abc.py:104 | has non-disjoint subclasses |
7-
| AssignmentDefinition | foo at code/b_condition.py:81 | has non-disjoint subclasses |
8-
| AssignmentDefinition | name at code/r_regressions.py:58 | has non-disjoint subclasses |
9-
| AssignmentDefinition | x at code/b_condition.py:87 | has non-disjoint subclasses |
10-
| AssignmentDefinition | x at code/c_tests.py:71 | has non-disjoint subclasses |
11-
| AssignmentDefinition | x at code/l_calls.py:3 | has non-disjoint subclasses |
12-
| AssignmentDefinition | x at code/l_calls.py:6 | has non-disjoint subclasses |
13-
| AssignmentDefinition | y at code/b_condition.py:87 | has non-disjoint subclasses |
14-
| AssignmentDefinition | y at code/c_tests.py:71 | has non-disjoint subclasses |
15-
| AssignmentDefinition | y at code/r_regressions.py:27 | has non-disjoint subclasses |
16-
| AssignmentDefinition | z at code/l_calls.py:48 | has non-disjoint subclasses |
17-
| AssignmentDefinition | z at code/r_regressions.py:27 | has non-disjoint subclasses |
18-
| ParameterDefinition | a at code/m_attributes.py:5 | has non-disjoint subclasses |
19-
| ParameterDefinition | b at code/a_simple.py:38 | has non-disjoint subclasses |
20-
| ParameterDefinition | c at code/a_simple.py:38 | has non-disjoint subclasses |
21-
| ParameterDefinition | compile_ops at code/n_nesting.py:8 | has non-disjoint subclasses |
22-
| ParameterDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/_py_abc.py:72 | has non-disjoint subclasses |
23-
| ParameterDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/abc.py:104 | has non-disjoint subclasses |
24-
| ParameterDefinition | foo at code/b_condition.py:81 | has non-disjoint subclasses |
25-
| ParameterDefinition | name at code/r_regressions.py:58 | has non-disjoint subclasses |
26-
| ParameterDefinition | x at code/b_condition.py:87 | has non-disjoint subclasses |
27-
| ParameterDefinition | x at code/c_tests.py:71 | has non-disjoint subclasses |
28-
| ParameterDefinition | x at code/l_calls.py:3 | has non-disjoint subclasses |
29-
| ParameterDefinition | x at code/l_calls.py:6 | has non-disjoint subclasses |
30-
| ParameterDefinition | y at code/b_condition.py:87 | has non-disjoint subclasses |
31-
| ParameterDefinition | y at code/c_tests.py:71 | has non-disjoint subclasses |
32-
| ParameterDefinition | y at code/r_regressions.py:27 | has non-disjoint subclasses |
33-
| ParameterDefinition | z at code/l_calls.py:48 | has non-disjoint subclasses |
34-
| ParameterDefinition | z at code/r_regressions.py:27 | has non-disjoint subclasses |

python/ql/test/library-tests/PointsTo/new/Dataflow.expected

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
| a_simple.py:34 | f_0 = FunctionExpr |
4949
| a_simple.py:34 | kwargs_0 = ParameterDefinition |
5050
| a_simple.py:38 | a_0 = ParameterDefinition |
51-
| a_simple.py:38 | b_0 = Str |
52-
| a_simple.py:38 | c_0 = Str |
51+
| a_simple.py:38 | b_0 = ParameterDefinition |
52+
| a_simple.py:38 | c_0 = ParameterDefinition |
5353
| a_simple.py:38 | multi_assign_and_packing_0 = FunctionExpr |
5454
| a_simple.py:39 | t_0 = Tuple |
5555
| a_simple.py:40 | w_0 = Tuple |
@@ -151,16 +151,16 @@
151151
| b_condition.py:79 | t_4 = ArgumentRefinement(t_3) |
152152
| b_condition.py:81 | bar_0 = ScopeEntryDefinition |
153153
| b_condition.py:81 | bar_2 = phi(bar_0, bar_1) |
154-
| b_condition.py:81 | foo_0 = True |
154+
| b_condition.py:81 | foo_0 = ParameterDefinition |
155155
| b_condition.py:81 | foo_3 = Pi(foo_0) [false] |
156156
| b_condition.py:81 | foo_4 = phi(foo_1, foo_3) |
157157
| b_condition.py:81 | odasa6261_1 = FunctionExpr |
158158
| b_condition.py:83 | bar_1 = FunctionExpr |
159159
| b_condition.py:83 | foo_1 = Pi(foo_0) [true] |
160160
| b_condition.py:83 | foo_2 = ScopeEntryDefinition |
161161
| b_condition.py:87 | split_bool1_1 = FunctionExpr |
162-
| b_condition.py:87 | x_0 = None |
163-
| b_condition.py:87 | y_0 = None |
162+
| b_condition.py:87 | x_0 = ParameterDefinition |
163+
| b_condition.py:87 | y_0 = ParameterDefinition |
164164
| b_condition.py:88 | x_1 = Pi(x_0) [true] |
165165
| b_condition.py:90 | x_4 = Pi(x_0) [false] |
166166
| b_condition.py:90 | x_5 = SingleSuccessorGuard(x_4) [false] |
@@ -643,7 +643,7 @@
643643
| n_nesting.py:0 | __name___0 = ScopeEntryDefinition |
644644
| n_nesting.py:0 | __package___0 = ScopeEntryDefinition |
645645
| n_nesting.py:8 | C_0 = ScopeEntryDefinition |
646-
| n_nesting.py:8 | compile_ops_0 = True |
646+
| n_nesting.py:8 | compile_ops_0 = ParameterDefinition |
647647
| n_nesting.py:8 | foo_0 = FunctionExpr |
648648
| n_nesting.py:9 | C_1 = CallsiteRefinement(C_0) |
649649
| n_nesting.py:10 | C_5 = ScopeEntryDefinition |
@@ -722,10 +722,10 @@
722722
| r_regressions.py:27 | gv_33 = phi(gv_12, gv_13) |
723723
| r_regressions.py:27 | x_0 = ParameterDefinition |
724724
| r_regressions.py:27 | x_5 = phi(x_3, x_4) |
725-
| r_regressions.py:27 | y_0 = None |
725+
| r_regressions.py:27 | y_0 = ParameterDefinition |
726726
| r_regressions.py:27 | y_7 = Pi(y_2) [false] |
727727
| r_regressions.py:27 | y_8 = phi(y_3, y_6, y_7) |
728-
| r_regressions.py:27 | z_0 = IntegerLiteral |
728+
| r_regressions.py:27 | z_0 = ParameterDefinition |
729729
| r_regressions.py:27 | z_3 = Pi(z_0) [false] |
730730
| r_regressions.py:27 | z_4 = phi(z_0, z_2, z_3) |
731731
| r_regressions.py:31 | x_1 = Pi(x_0) [true] |
@@ -761,7 +761,7 @@
761761
| r_regressions.py:58 | decorator_0 = ParameterDefinition |
762762
| r_regressions.py:58 | gv_19 = ScopeEntryDefinition |
763763
| r_regressions.py:58 | method_decorator_0 = FunctionExpr |
764-
| r_regressions.py:58 | name_0 = Str |
764+
| r_regressions.py:58 | name_0 = ParameterDefinition |
765765
| r_regressions.py:61 | _dec_0 = FunctionExpr |
766766
| r_regressions.py:61 | func_0 = ScopeEntryDefinition |
767767
| r_regressions.py:61 | gv_20 = ScopeEntryDefinition |

python/ql/test/library-tests/PointsTo/new/Definitions.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
| a_simple.py:34 | Local Variable kwargs | ParameterDefinition |
3333
| a_simple.py:38 | Global Variable multi_assign_and_packing | AssignmentDefinition |
3434
| a_simple.py:38 | Local Variable a | ParameterDefinition |
35-
| a_simple.py:38 | Local Variable b | AssignmentDefinition |
3635
| a_simple.py:38 | Local Variable b | ParameterDefinition |
37-
| a_simple.py:38 | Local Variable c | AssignmentDefinition |
3836
| a_simple.py:38 | Local Variable c | ParameterDefinition |
3937
| a_simple.py:39 | Local Variable t | AssignmentDefinition |
4038
| a_simple.py:40 | Local Variable w | AssignmentDefinition |
@@ -134,17 +132,14 @@
134132
| b_condition.py:81 | Global Variable odasa6261 | AssignmentDefinition |
135133
| b_condition.py:81 | Local Variable bar | PhiFunction |
136134
| b_condition.py:81 | Local Variable bar | ScopeEntryDefinition |
137-
| b_condition.py:81 | Local Variable foo | AssignmentDefinition |
138135
| b_condition.py:81 | Local Variable foo | ParameterDefinition |
139136
| b_condition.py:81 | Local Variable foo | PhiFunction |
140137
| b_condition.py:81 | Local Variable foo | PyEdgeRefinement |
141138
| b_condition.py:83 | Local Variable bar | AssignmentDefinition |
142139
| b_condition.py:83 | Local Variable foo | PyEdgeRefinement |
143140
| b_condition.py:83 | Local Variable foo | ScopeEntryDefinition |
144141
| b_condition.py:87 | Global Variable split_bool1 | AssignmentDefinition |
145-
| b_condition.py:87 | Local Variable x | AssignmentDefinition |
146142
| b_condition.py:87 | Local Variable x | ParameterDefinition |
147-
| b_condition.py:87 | Local Variable y | AssignmentDefinition |
148143
| b_condition.py:87 | Local Variable y | ParameterDefinition |
149144
| b_condition.py:88 | Local Variable x | PyEdgeRefinement |
150145
| b_condition.py:90 | Local Variable x | PyEdgeRefinement |

python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
| code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:10:1:10:9 | ControlFlowNode for type() |
22
| code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:15:5:15:13 | ControlFlowNode for type() |
3+
| code/l_calls.py:3:13:3:14 | ControlFlowNode for List | code/l_calls.py:4:12:4:12 | ControlFlowNode for x |
4+
| code/l_calls.py:6:13:6:14 | ControlFlowNode for List | code/l_calls.py:7:16:7:16 | ControlFlowNode for x |
35
| code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:16:16:16:18 | ControlFlowNode for cls |
46
| code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:24:13:24:22 | ControlFlowNode for Attribute() |
57
| code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:25:16:25:16 | ControlFlowNode for a |

python/ql/test/library-tests/PointsTo/new/SSA.expected

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
| a_simple.py:23 | with_definition_0 = FunctionExpr | Function with_definition | builtin-class function |
2626
| a_simple.py:27 | multi_loop_in_try_0 = FunctionExpr | Function multi_loop_in_try | builtin-class function |
2727
| a_simple.py:34 | f_0 = FunctionExpr | Function f | builtin-class function |
28-
| a_simple.py:38 | b_0 = Str | 'b' | builtin-class str |
29-
| a_simple.py:38 | c_0 = Str | 'c' | builtin-class str |
28+
| a_simple.py:38 | b_0 = ParameterDefinition | 'b' | builtin-class str |
29+
| a_simple.py:38 | c_0 = ParameterDefinition | 'c' | builtin-class str |
3030
| a_simple.py:38 | multi_assign_and_packing_0 = FunctionExpr | Function multi_assign_and_packing | builtin-class function |
3131
| a_simple.py:39 | t_0 = Tuple | Tuple | builtin-class tuple |
3232
| a_simple.py:40 | w_0 = Tuple | Tuple | builtin-class tuple |
@@ -81,14 +81,14 @@
8181
| b_condition.py:79 | t_3 = phi(t_1, t_2) | builtin-class object | builtin-class type |
8282
| b_condition.py:79 | t_4 = ArgumentRefinement(t_3) | builtin-class object | builtin-class type |
8383
| b_condition.py:81 | bar_2 = phi(bar_0, bar_1) | Function bar | builtin-class function |
84-
| b_condition.py:81 | foo_0 = True | bool True | builtin-class bool |
84+
| b_condition.py:81 | foo_0 = ParameterDefinition | bool True | builtin-class bool |
8585
| b_condition.py:81 | foo_3 = Pi(foo_0) [false] | bool True | builtin-class bool |
8686
| b_condition.py:81 | foo_4 = phi(foo_1, foo_3) | bool True | builtin-class bool |
8787
| b_condition.py:81 | odasa6261_1 = FunctionExpr | Function odasa6261 | builtin-class function |
8888
| b_condition.py:83 | bar_1 = FunctionExpr | Function bar | builtin-class function |
8989
| b_condition.py:87 | split_bool1_1 = FunctionExpr | Function split_bool1 | builtin-class function |
90-
| b_condition.py:87 | x_0 = None | NoneType None | builtin-class NoneType |
91-
| b_condition.py:87 | y_0 = None | NoneType None | builtin-class NoneType |
90+
| b_condition.py:87 | x_0 = ParameterDefinition | NoneType None | builtin-class NoneType |
91+
| b_condition.py:87 | y_0 = ParameterDefinition | NoneType None | builtin-class NoneType |
9292
| b_condition.py:90 | x_4 = Pi(x_0) [false] | NoneType None | builtin-class NoneType |
9393
| b_condition.py:90 | x_5 = SingleSuccessorGuard(x_4) [false] | NoneType None | builtin-class NoneType |
9494
| b_condition.py:90 | y_4 = Pi(y_0) [false] | NoneType None | builtin-class NoneType |
@@ -140,8 +140,8 @@
140140
| c_tests.py:68 | x_5 = phi(x_3, x_4) | int 0 | builtin-class int |
141141
| c_tests.py:69 | x_6 = Pi(x_5) [true] | builtin-class float | builtin-class type |
142142
| c_tests.py:71 | compound_0 = FunctionExpr | Function compound | builtin-class function |
143-
| c_tests.py:71 | x_0 = IntegerLiteral | int 1 | builtin-class int |
144-
| c_tests.py:71 | y_0 = IntegerLiteral | int 0 | builtin-class int |
143+
| c_tests.py:71 | x_0 = ParameterDefinition | int 1 | builtin-class int |
144+
| c_tests.py:71 | y_0 = ParameterDefinition | int 0 | builtin-class int |
145145
| c_tests.py:71 | y_5 = Pi(y_0) [false] | int 0 | builtin-class int |
146146
| c_tests.py:71 | y_6 = phi(y_4, y_5) | int 0 | builtin-class int |
147147
| c_tests.py:74 | x_2 = Pi(x_0) [true] | int 1 | builtin-class int |
@@ -387,8 +387,8 @@
387387
| m_attributes.py:0 | __name___0 = ScopeEntryDefinition | 'code.m_attributes' | builtin-class str |
388388
| m_attributes.py:3 | C_0 = ClassExpr | class C | builtin-class type |
389389
| m_attributes.py:5 | __init___0 = FunctionExpr | Function __init__ | builtin-class function |
390-
| m_attributes.py:5 | a_0 = IntegerLiteral | int 17 | builtin-class int |
391-
| m_attributes.py:5 | a_0 = IntegerLiteral | int 100 | builtin-class int |
390+
| m_attributes.py:5 | a_0 = ParameterDefinition | int 17 | builtin-class int |
391+
| m_attributes.py:5 | a_0 = ParameterDefinition | int 100 | builtin-class int |
392392
| m_attributes.py:5 | self_0 = ParameterDefinition | self | class C |
393393
| m_attributes.py:6 | self_1 = AttributeAssignment 'a'(self_0) | self | class C |
394394
| m_attributes.py:8 | foo_0 = FunctionExpr | Function foo | builtin-class function |
@@ -397,7 +397,7 @@
397397
| m_attributes.py:8 | self_0 = ParameterDefinition | self | class C |
398398
| n_nesting.py:0 | __name___0 = ScopeEntryDefinition | 'code.n_nesting' | builtin-class str |
399399
| n_nesting.py:8 | C_0 = ScopeEntryDefinition | int 1 | builtin-class int |
400-
| n_nesting.py:8 | compile_ops_0 = True | bool True | builtin-class bool |
400+
| n_nesting.py:8 | compile_ops_0 = ParameterDefinition | bool True | builtin-class bool |
401401
| n_nesting.py:8 | foo_0 = FunctionExpr | Function foo | builtin-class function |
402402
| n_nesting.py:9 | C_1 = CallsiteRefinement(C_0) | int 1 | builtin-class int |
403403
| n_nesting.py:10 | C_5 = ScopeEntryDefinition | int 1 | builtin-class int |

0 commit comments

Comments
 (0)