Skip to content

Commit 5c3109a

Browse files
committed
Python: Fix bug in multi_assignment_points_to.
This turned out to be a fairly simple but easy to make bug. When we want to figure out the value pointed-to in a multi-assignment, we look at the left hand side to see what value from the right hand side we should assign. Unfortunately, we accidentally attempted to look up this information in the _left hand side_ of the assignment, resulting in no points-to information at all. The only thing needed to fix this was to properly link up the left and right hand sides: using the left hand side to figure out what index to look at, and then looking up the points-to information for the corresponding place in the right hand side.
1 parent abbc929 commit 5c3109a

6 files changed

Lines changed: 26 additions & 2 deletions

File tree

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,9 @@ cached module PointsToInternal {
508508

509509
pragma [noinline]
510510
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
511+
exists(int index, ControlFlowNode lhs, ControlFlowNode rhs, SequenceObjectInternal sequence |
512+
def.indexOf(index, lhs) and
513+
lhs.(DefinitionNode).getValue() = rhs and
513514
sequence_index_points_to(rhs, context, sequence, value, index) and
514515
origin = def.getDefiningNode()
515516
)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
| a_simple.py:40 | ControlFlowNode for a | 38 |
99
| a_simple.py:40 | ControlFlowNode for b | 38 |
1010
| a_simple.py:40 | ControlFlowNode for c | 38 |
11+
| a_simple.py:46 | ControlFlowNode for x | 42 |
12+
| a_simple.py:47 | ControlFlowNode for y | 42 |
13+
| a_simple.py:48 | ControlFlowNode for z | 42 |
1114
| a_simple.py:49 | ControlFlowNode for a | 38 |
1215
| a_simple.py:49 | ControlFlowNode for b | 38 |
1316
| a_simple.py:49 | ControlFlowNode for c | 38 |

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ 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 |

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ 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 |

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/Values.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
| a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple |
4242
| a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple |
4343
| a_simple.py:42 | ControlFlowNode for w | runtime | (Unknown value, Unknown value, Unknown value, ) | builtin-class tuple |
44+
| a_simple.py:43 | ControlFlowNode for p | runtime | int 1 | builtin-class int |
45+
| a_simple.py:44 | ControlFlowNode for q | runtime | int 2 | builtin-class int |
46+
| a_simple.py:45 | ControlFlowNode for r | runtime | int 3 | builtin-class int |
47+
| a_simple.py:47 | ControlFlowNode for y | runtime | 'b' | builtin-class str |
48+
| a_simple.py:48 | ControlFlowNode for z | runtime | 'c' | builtin-class str |
4449
| a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', 'c', ) | builtin-class tuple |
4550
| a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, 'b', Unknown value, ) | builtin-class tuple |
4651
| a_simple.py:49 | ControlFlowNode for Tuple | runtime | (Unknown value, Unknown value, 'c', ) | builtin-class tuple |

0 commit comments

Comments
 (0)