Skip to content

Commit 290e33a

Browse files
authored
Merge pull request github#2922 from tausbn/python-fix-multi-assign-points-to
Python: Fix bug in `multi_assignment_points_to`.
2 parents b030315 + c724b17 commit 290e33a

File tree

16 files changed

+105
-8
lines changed

16 files changed

+105
-8
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ class MultiAssignmentDefinition extends EssaNodeDefinition {
608608
)
609609
}
610610

611+
/** Holds if `this` has (zero-based) index `index` in `lhs`. */
611612
predicate indexOf(int index, SequenceNode lhs) {
612613
SsaSource::multi_assignment_definition(this.getSourceVariable(), this.getDefiningNode(), index, lhs)
613614
}

python/ql/src/semmle/python/pointsto/PointsTo.qll

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,21 @@ cached module PointsToInternal {
506506
value = sequence.getItem(index)
507507
}
508508

509-
pragma [noinline]
510-
private predicate multi_assignment_points_to(MultiAssignmentDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
511-
exists(int index, ControlFlowNode rhs, SequenceObjectInternal sequence |
512-
def.indexOf(index, rhs) and
513-
sequence_index_points_to(rhs, context, sequence, value, index) and
509+
pragma[noinline]
510+
private predicate multi_assignment_points_to(
511+
MultiAssignmentDefinition def, PointsToContext context, ObjectInternal value,
512+
ControlFlowNode origin
513+
) {
514+
exists(int index, ControlFlowNode lhs, ControlFlowNode rhs, ObjectInternal sequence |
515+
def.indexOf(index, lhs) and
516+
lhs.(DefinitionNode).getValue() = rhs and
514517
origin = def.getDefiningNode()
518+
|
519+
sequence_index_points_to(rhs, context, sequence, value, index)
520+
or
521+
pointsTo(rhs, context, sequence, _) and
522+
sequence.subscriptUnknown() and
523+
value = TUnknown()
515524
)
516525
}
517526

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
| a_simple.py:49 | g_0 = a |
6363
| a_simple.py:49 | h_0 = b |
6464
| a_simple.py:49 | i_0 = c |
65+
| a_simple.py:53 | l_0 = BinaryExpr[0] |
66+
| a_simple.py:53 | m_0 = BinaryExpr[1] |
67+
| a_simple.py:56 | s_0 = a[0] |
68+
| a_simple.py:56 | u_0 = a[1] |
6569
| b_condition.py:0 | __name___0 = ScopeEntryDefinition |
6670
| b_condition.py:0 | __package___0 = ScopeEntryDefinition |
6771
| b_condition.py:0 | double_attr_check_0 = ScopeEntryDefinition |

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
| a_simple.py:49 | Local Variable g | AssignmentDefinition |
4646
| a_simple.py:49 | Local Variable h | AssignmentDefinition |
4747
| a_simple.py:49 | Local Variable i | AssignmentDefinition |
48+
| a_simple.py:53 | Local Variable l | MultiAssignmentDefinition |
49+
| a_simple.py:53 | Local Variable m | MultiAssignmentDefinition |
50+
| a_simple.py:56 | Local Variable s | MultiAssignmentDefinition |
51+
| a_simple.py:56 | Local Variable u | MultiAssignmentDefinition |
4852
| b_condition.py:0 | Global Variable __name__ | ScopeEntryDefinition |
4953
| b_condition.py:0 | Global Variable __package__ | ScopeEntryDefinition |
5054
| b_condition.py:0 | Global Variable double_attr_check | ScopeEntryDefinition |

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
| a_simple.py:20 | ControlFlowNode for For | 20 |
22
| a_simple.py:20 | ControlFlowNode for seq | 18 |
3+
| a_simple.py:21 | ControlFlowNode for x | 20 |
34
| a_simple.py:24 | ControlFlowNode for x | 23 |
45
| a_simple.py:29 | ControlFlowNode for For | 29 |
56
| a_simple.py:29 | ControlFlowNode for x | 27 |
7+
| a_simple.py:30 | ControlFlowNode for p | 29 |
68
| a_simple.py:35 | ControlFlowNode for Subscript | 35 |
79
| a_simple.py:36 | ControlFlowNode for Subscript | 36 |
810
| a_simple.py:40 | ControlFlowNode for a | 38 |
911
| a_simple.py:40 | ControlFlowNode for b | 38 |
1012
| a_simple.py:40 | ControlFlowNode for c | 38 |
13+
| a_simple.py:46 | ControlFlowNode for x | 42 |
14+
| a_simple.py:47 | ControlFlowNode for y | 42 |
15+
| a_simple.py:48 | ControlFlowNode for z | 42 |
1116
| a_simple.py:49 | ControlFlowNode for a | 38 |
1217
| a_simple.py:49 | ControlFlowNode for b | 38 |
1318
| a_simple.py:49 | ControlFlowNode for c | 38 |
1419
| a_simple.py:50 | ControlFlowNode for g | 38 |
1520
| a_simple.py:51 | ControlFlowNode for h | 38 |
1621
| a_simple.py:52 | ControlFlowNode for i | 38 |
22+
| a_simple.py:54 | ControlFlowNode for l | 53 |
23+
| a_simple.py:55 | ControlFlowNode for m | 53 |
24+
| a_simple.py:56 | ControlFlowNode for a | 38 |
25+
| a_simple.py:57 | ControlFlowNode for s | 56 |
26+
| a_simple.py:58 | ControlFlowNode for u | 56 |
1727
| b_condition.py:5 | ControlFlowNode for IfExp | 5 |
1828
| b_condition.py:5 | ControlFlowNode for cond | 5 |
1929
| b_condition.py:5 | ControlFlowNode for unknown | 5 |
@@ -231,6 +241,7 @@
231241
| r_regressions.py:39 | ControlFlowNode for y | 27 |
232242
| r_regressions.py:43 | ControlFlowNode for x | 43 |
233243
| r_regressions.py:43 | ControlFlowNode for x() | 43 |
244+
| r_regressions.py:44 | ControlFlowNode for data | 43 |
234245
| r_regressions.py:52 | ControlFlowNode for msg | 51 |
235246
| r_regressions.py:64 | ControlFlowNode for do_validation | 64 |
236247
| r_regressions.py:64 | ControlFlowNode for do_validation() | 64 |

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,23 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
5656
| a_simple.py:41 | ControlFlowNode for t | Tuple | builtin-class tuple | 39 | runtime |
5757
| a_simple.py:42 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 40 | runtime |
5858
| a_simple.py:42 | ControlFlowNode for w | Tuple | builtin-class tuple | 40 | runtime |
59+
| a_simple.py:43 | ControlFlowNode for p | int 1 | builtin-class int | 41 | runtime |
60+
| a_simple.py:44 | ControlFlowNode for q | int 2 | builtin-class int | 41 | runtime |
61+
| a_simple.py:45 | ControlFlowNode for r | int 3 | builtin-class int | 41 | runtime |
62+
| a_simple.py:47 | ControlFlowNode for y | 'b' | builtin-class str | 42 | runtime |
63+
| a_simple.py:48 | ControlFlowNode for z | 'c' | builtin-class str | 42 | runtime |
5964
| a_simple.py:49 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 49 | runtime |
6065
| a_simple.py:49 | ControlFlowNode for b | 'b' | builtin-class str | 38 | runtime |
6166
| a_simple.py:49 | ControlFlowNode for c | 'c' | builtin-class str | 38 | runtime |
6267
| a_simple.py:49 | ControlFlowNode for h | 'b' | builtin-class str | 38 | runtime |
6368
| a_simple.py:49 | ControlFlowNode for i | 'c' | builtin-class str | 38 | runtime |
6469
| a_simple.py:51 | ControlFlowNode for h | 'b' | builtin-class str | 38 | runtime |
6570
| a_simple.py:52 | ControlFlowNode for i | 'c' | builtin-class str | 38 | runtime |
71+
| a_simple.py:53 | ControlFlowNode for BinaryExpr | BinaryExpr | builtin-class tuple | 53 | runtime |
72+
| a_simple.py:53 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 53 | runtime |
73+
| a_simple.py:53 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 53 | runtime |
74+
| a_simple.py:53 | ControlFlowNode for Tuple | BinaryExpr | builtin-class tuple | 53 | runtime |
75+
| a_simple.py:53 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 53 | runtime |
6676
| b_condition.py:4 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 4 | import |
6777
| b_condition.py:4 | ControlFlowNode for f | Function f | builtin-class function | 4 | import |
6878
| b_condition.py:5 | ControlFlowNode for IfExp | NoneType None | builtin-class NoneType | 5 | runtime |

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,23 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
5656
| a_simple.py:41 | ControlFlowNode for t | Tuple | builtin-class tuple | 39 |
5757
| a_simple.py:42 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 40 |
5858
| a_simple.py:42 | ControlFlowNode for w | Tuple | builtin-class tuple | 40 |
59+
| a_simple.py:43 | ControlFlowNode for p | int 1 | builtin-class int | 41 |
60+
| a_simple.py:44 | ControlFlowNode for q | int 2 | builtin-class int | 41 |
61+
| a_simple.py:45 | ControlFlowNode for r | int 3 | builtin-class int | 41 |
62+
| a_simple.py:47 | ControlFlowNode for y | 'b' | builtin-class str | 42 |
63+
| a_simple.py:48 | ControlFlowNode for z | 'c' | builtin-class str | 42 |
5964
| a_simple.py:49 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 49 |
6065
| a_simple.py:49 | ControlFlowNode for b | 'b' | builtin-class str | 38 |
6166
| a_simple.py:49 | ControlFlowNode for c | 'c' | builtin-class str | 38 |
6267
| a_simple.py:49 | ControlFlowNode for h | 'b' | builtin-class str | 38 |
6368
| a_simple.py:49 | ControlFlowNode for i | 'c' | builtin-class str | 38 |
6469
| a_simple.py:51 | ControlFlowNode for h | 'b' | builtin-class str | 38 |
6570
| a_simple.py:52 | ControlFlowNode for i | 'c' | builtin-class str | 38 |
71+
| a_simple.py:53 | ControlFlowNode for BinaryExpr | BinaryExpr | builtin-class tuple | 53 |
72+
| a_simple.py:53 | ControlFlowNode for IntegerLiteral | int 1 | builtin-class int | 53 |
73+
| a_simple.py:53 | ControlFlowNode for IntegerLiteral | int 2 | builtin-class int | 53 |
74+
| a_simple.py:53 | ControlFlowNode for Tuple | BinaryExpr | builtin-class tuple | 53 |
75+
| a_simple.py:53 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 53 |
6676
| b_condition.py:4 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 4 |
6777
| b_condition.py:4 | ControlFlowNode for f | Function f | builtin-class function | 4 |
6878
| b_condition.py:5 | ControlFlowNode for IfExp | NoneType None | builtin-class NoneType | 5 |

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ WARNING: Predicate ssa_variable_points_to has been deprecated and may be removed
3131
| a_simple.py:38 | multi_assign_and_packing_0 = FunctionExpr | Function multi_assign_and_packing | builtin-class function |
3232
| a_simple.py:39 | t_0 = Tuple | Tuple | builtin-class tuple |
3333
| a_simple.py:40 | w_0 = Tuple | Tuple | builtin-class tuple |
34+
| a_simple.py:41 | p_0 = t[0] | int 1 | builtin-class int |
35+
| a_simple.py:41 | q_0 = t[1] | int 2 | builtin-class int |
36+
| a_simple.py:41 | r_0 = t[2] | int 3 | builtin-class int |
37+
| a_simple.py:42 | y_0 = w[1] | 'b' | builtin-class str |
38+
| a_simple.py:42 | z_0 = w[2] | 'c' | builtin-class str |
3439
| a_simple.py:49 | h_0 = b | 'b' | builtin-class str |
3540
| a_simple.py:49 | i_0 = c | 'c' | builtin-class str |
3641
| b_condition.py:0 | __name___0 = ScopeEntryDefinition | 'code.b_condition' | builtin-class str |

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,14 @@
4646
| a_simple.py:38 | Local Variable g | Entry node for Function multi_assign_and_packing | definition |
4747
| a_simple.py:38 | Local Variable h | Entry node for Function multi_assign_and_packing | definition |
4848
| a_simple.py:38 | Local Variable i | Entry node for Function multi_assign_and_packing | definition |
49+
| a_simple.py:38 | Local Variable l | Entry node for Function multi_assign_and_packing | definition |
50+
| a_simple.py:38 | Local Variable m | Entry node for Function multi_assign_and_packing | definition |
4951
| a_simple.py:38 | Local Variable p | Entry node for Function multi_assign_and_packing | definition |
5052
| a_simple.py:38 | Local Variable q | Entry node for Function multi_assign_and_packing | definition |
5153
| a_simple.py:38 | Local Variable r | Entry node for Function multi_assign_and_packing | definition |
54+
| a_simple.py:38 | Local Variable s | Entry node for Function multi_assign_and_packing | definition |
5255
| a_simple.py:38 | Local Variable t | Entry node for Function multi_assign_and_packing | definition |
56+
| a_simple.py:38 | Local Variable u | Entry node for Function multi_assign_and_packing | definition |
5357
| a_simple.py:38 | Local Variable w | Entry node for Function multi_assign_and_packing | definition |
5458
| a_simple.py:38 | Local Variable x | Entry node for Function multi_assign_and_packing | definition |
5559
| a_simple.py:38 | Local Variable y | Entry node for Function multi_assign_and_packing | definition |
@@ -65,6 +69,10 @@
6569
| a_simple.py:49 | Local Variable g | ControlFlowNode for g | definition |
6670
| a_simple.py:49 | Local Variable h | ControlFlowNode for h | definition |
6771
| a_simple.py:49 | Local Variable i | ControlFlowNode for i | definition |
72+
| a_simple.py:53 | Local Variable l | ControlFlowNode for l | definition |
73+
| a_simple.py:53 | Local Variable m | ControlFlowNode for m | definition |
74+
| a_simple.py:56 | Local Variable s | ControlFlowNode for s | definition |
75+
| a_simple.py:56 | Local Variable u | ControlFlowNode for u | definition |
6876
| b_condition.py:0 | Global Variable __name__ | Entry node for Module code.b_condition | definition |
6977
| b_condition.py:0 | Global Variable __package__ | Entry node for Module code.b_condition | definition |
7078
| b_condition.py:0 | Global Variable double_attr_check | Entry node for Module code.b_condition | definition |

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@
6262
| a_simple.py:38 | g_0 | Exit node for Function multi_assign_and_packing |
6363
| a_simple.py:38 | h_0 | Exit node for Function multi_assign_and_packing |
6464
| a_simple.py:38 | i_0 | Exit node for Function multi_assign_and_packing |
65+
| a_simple.py:38 | l_0 | Exit node for Function multi_assign_and_packing |
66+
| a_simple.py:38 | m_0 | Exit node for Function multi_assign_and_packing |
6567
| a_simple.py:38 | p_0 | Exit node for Function multi_assign_and_packing |
6668
| a_simple.py:38 | q_0 | Exit node for Function multi_assign_and_packing |
6769
| a_simple.py:38 | r_0 | Exit node for Function multi_assign_and_packing |
70+
| a_simple.py:38 | s_0 | Exit node for Function multi_assign_and_packing |
6871
| a_simple.py:38 | t_0 | Exit node for Function multi_assign_and_packing |
72+
| a_simple.py:38 | u_0 | Exit node for Function multi_assign_and_packing |
6973
| a_simple.py:38 | w_0 | Exit node for Function multi_assign_and_packing |
7074
| a_simple.py:38 | x_0 | Exit node for Function multi_assign_and_packing |
7175
| a_simple.py:38 | y_0 | Exit node for Function multi_assign_and_packing |
@@ -87,6 +91,11 @@
8791
| a_simple.py:50 | g_0 | ControlFlowNode for g |
8892
| a_simple.py:51 | h_0 | ControlFlowNode for h |
8993
| a_simple.py:52 | i_0 | ControlFlowNode for i |
94+
| a_simple.py:54 | l_0 | ControlFlowNode for l |
95+
| a_simple.py:55 | m_0 | ControlFlowNode for m |
96+
| a_simple.py:56 | a_0 | ControlFlowNode for a |
97+
| a_simple.py:57 | s_0 | ControlFlowNode for s |
98+
| a_simple.py:58 | u_0 | ControlFlowNode for u |
9099
| b_condition.py:0 | __name___0 | Exit node for Module code.b_condition |
91100
| b_condition.py:0 | __package___0 | Exit node for Module code.b_condition |
92101
| b_condition.py:0 | double_attr_check_1 | Exit node for Module code.b_condition |

0 commit comments

Comments
 (0)