diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index d6d8d0c1297..eafc16db734 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -292,12 +292,7 @@ module EssaFlow { // nodeFrom is `f(42)`, cfg node // nodeTo is `x`, essa var nodeFrom.(CfgNode).getNode() = - nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() and - // we need to ensure that enclosing callable is the same, since a parameter with a - // default value will be in the scope of the function, while the default value - // itself will be in the scope that _defines_ the function. - // We handle _that_ as a jumpstep - nodeFrom.getEnclosingCallable() = nodeTo.getEnclosingCallable() + nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() or // With definition // `with f(42) as x:` @@ -473,8 +468,7 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) { // function, while the default value itself will be in the scope that _defines_ the // function. nodeFrom.(CfgNode).getNode() = - nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() and - not nodeFrom.getEnclosingCallable() = nodeTo.getEnclosingCallable() + nodeTo.(EssaNode).getVar().getDefinition().(ParameterDefinition).getDefault() } /** diff --git a/python/ql/lib/semmle/python/essa/Essa.qll b/python/ql/lib/semmle/python/essa/Essa.qll index cf2aca1e2ac..6e9d328f7d5 100644 --- a/python/ql/lib/semmle/python/essa/Essa.qll +++ b/python/ql/lib/semmle/python/essa/Essa.qll @@ -501,7 +501,8 @@ class AssignmentDefinition extends EssaNodeDefinition { ControlFlowNode value; AssignmentDefinition() { - SsaSource::assignment_definition(this.getSourceVariable(), this.getDefiningNode(), value) + SsaSource::assignment_definition(this.getSourceVariable(), this.getDefiningNode(), value) and + not this instanceof ParameterDefinition } ControlFlowNode getValue() { result = value } diff --git a/python/ql/test/library-tests/PointsTo/new/Consistency.expected b/python/ql/test/library-tests/PointsTo/new/Consistency.expected index 194456bd452..e69de29bb2d 100644 --- a/python/ql/test/library-tests/PointsTo/new/Consistency.expected +++ b/python/ql/test/library-tests/PointsTo/new/Consistency.expected @@ -1,34 +0,0 @@ -| AssignmentDefinition | a at code/m_attributes.py:5 | has non-disjoint subclasses | -| AssignmentDefinition | b at code/a_simple.py:38 | has non-disjoint subclasses | -| AssignmentDefinition | c at code/a_simple.py:38 | has non-disjoint subclasses | -| AssignmentDefinition | compile_ops at code/n_nesting.py:8 | has non-disjoint subclasses | -| AssignmentDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/_py_abc.py:72 | has non-disjoint subclasses | -| AssignmentDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/abc.py:104 | has non-disjoint subclasses | -| AssignmentDefinition | foo at code/b_condition.py:81 | has non-disjoint subclasses | -| AssignmentDefinition | name at code/r_regressions.py:58 | has non-disjoint subclasses | -| AssignmentDefinition | x at code/b_condition.py:87 | has non-disjoint subclasses | -| AssignmentDefinition | x at code/c_tests.py:71 | has non-disjoint subclasses | -| AssignmentDefinition | x at code/l_calls.py:3 | has non-disjoint subclasses | -| AssignmentDefinition | x at code/l_calls.py:6 | has non-disjoint subclasses | -| AssignmentDefinition | y at code/b_condition.py:87 | has non-disjoint subclasses | -| AssignmentDefinition | y at code/c_tests.py:71 | has non-disjoint subclasses | -| AssignmentDefinition | y at code/r_regressions.py:27 | has non-disjoint subclasses | -| AssignmentDefinition | z at code/l_calls.py:48 | has non-disjoint subclasses | -| AssignmentDefinition | z at code/r_regressions.py:27 | has non-disjoint subclasses | -| ParameterDefinition | a at code/m_attributes.py:5 | has non-disjoint subclasses | -| ParameterDefinition | b at code/a_simple.py:38 | has non-disjoint subclasses | -| ParameterDefinition | c at code/a_simple.py:38 | has non-disjoint subclasses | -| ParameterDefinition | compile_ops at code/n_nesting.py:8 | has non-disjoint subclasses | -| ParameterDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/_py_abc.py:72 | has non-disjoint subclasses | -| ParameterDefinition | file at /home/rasmus/.pyenv/versions/3.9.5/lib/python3.9/abc.py:104 | has non-disjoint subclasses | -| ParameterDefinition | foo at code/b_condition.py:81 | has non-disjoint subclasses | -| ParameterDefinition | name at code/r_regressions.py:58 | has non-disjoint subclasses | -| ParameterDefinition | x at code/b_condition.py:87 | has non-disjoint subclasses | -| ParameterDefinition | x at code/c_tests.py:71 | has non-disjoint subclasses | -| ParameterDefinition | x at code/l_calls.py:3 | has non-disjoint subclasses | -| ParameterDefinition | x at code/l_calls.py:6 | has non-disjoint subclasses | -| ParameterDefinition | y at code/b_condition.py:87 | has non-disjoint subclasses | -| ParameterDefinition | y at code/c_tests.py:71 | has non-disjoint subclasses | -| ParameterDefinition | y at code/r_regressions.py:27 | has non-disjoint subclasses | -| ParameterDefinition | z at code/l_calls.py:48 | has non-disjoint subclasses | -| ParameterDefinition | z at code/r_regressions.py:27 | has non-disjoint subclasses | diff --git a/python/ql/test/library-tests/PointsTo/new/Dataflow.expected b/python/ql/test/library-tests/PointsTo/new/Dataflow.expected index abe94891d24..aeee23bce72 100644 --- a/python/ql/test/library-tests/PointsTo/new/Dataflow.expected +++ b/python/ql/test/library-tests/PointsTo/new/Dataflow.expected @@ -48,8 +48,8 @@ | a_simple.py:34 | f_0 = FunctionExpr | | a_simple.py:34 | kwargs_0 = ParameterDefinition | | a_simple.py:38 | a_0 = ParameterDefinition | -| a_simple.py:38 | b_0 = Str | -| a_simple.py:38 | c_0 = Str | +| a_simple.py:38 | b_0 = ParameterDefinition | +| a_simple.py:38 | c_0 = ParameterDefinition | | a_simple.py:38 | multi_assign_and_packing_0 = FunctionExpr | | a_simple.py:39 | t_0 = Tuple | | a_simple.py:40 | w_0 = Tuple | @@ -151,7 +151,7 @@ | b_condition.py:79 | t_4 = ArgumentRefinement(t_3) | | b_condition.py:81 | bar_0 = ScopeEntryDefinition | | b_condition.py:81 | bar_2 = phi(bar_0, bar_1) | -| b_condition.py:81 | foo_0 = True | +| b_condition.py:81 | foo_0 = ParameterDefinition | | b_condition.py:81 | foo_3 = Pi(foo_0) [false] | | b_condition.py:81 | foo_4 = phi(foo_1, foo_3) | | b_condition.py:81 | odasa6261_1 = FunctionExpr | @@ -159,8 +159,8 @@ | b_condition.py:83 | foo_1 = Pi(foo_0) [true] | | b_condition.py:83 | foo_2 = ScopeEntryDefinition | | b_condition.py:87 | split_bool1_1 = FunctionExpr | -| b_condition.py:87 | x_0 = None | -| b_condition.py:87 | y_0 = None | +| b_condition.py:87 | x_0 = ParameterDefinition | +| b_condition.py:87 | y_0 = ParameterDefinition | | b_condition.py:88 | x_1 = Pi(x_0) [true] | | b_condition.py:90 | x_4 = Pi(x_0) [false] | | b_condition.py:90 | x_5 = SingleSuccessorGuard(x_4) [false] | @@ -643,7 +643,7 @@ | n_nesting.py:0 | __name___0 = ScopeEntryDefinition | | n_nesting.py:0 | __package___0 = ScopeEntryDefinition | | n_nesting.py:8 | C_0 = ScopeEntryDefinition | -| n_nesting.py:8 | compile_ops_0 = True | +| n_nesting.py:8 | compile_ops_0 = ParameterDefinition | | n_nesting.py:8 | foo_0 = FunctionExpr | | n_nesting.py:9 | C_1 = CallsiteRefinement(C_0) | | n_nesting.py:10 | C_5 = ScopeEntryDefinition | @@ -722,10 +722,10 @@ | r_regressions.py:27 | gv_33 = phi(gv_12, gv_13) | | r_regressions.py:27 | x_0 = ParameterDefinition | | r_regressions.py:27 | x_5 = phi(x_3, x_4) | -| r_regressions.py:27 | y_0 = None | +| r_regressions.py:27 | y_0 = ParameterDefinition | | r_regressions.py:27 | y_7 = Pi(y_2) [false] | | r_regressions.py:27 | y_8 = phi(y_3, y_6, y_7) | -| r_regressions.py:27 | z_0 = IntegerLiteral | +| r_regressions.py:27 | z_0 = ParameterDefinition | | r_regressions.py:27 | z_3 = Pi(z_0) [false] | | r_regressions.py:27 | z_4 = phi(z_0, z_2, z_3) | | r_regressions.py:31 | x_1 = Pi(x_0) [true] | @@ -761,7 +761,7 @@ | r_regressions.py:58 | decorator_0 = ParameterDefinition | | r_regressions.py:58 | gv_19 = ScopeEntryDefinition | | r_regressions.py:58 | method_decorator_0 = FunctionExpr | -| r_regressions.py:58 | name_0 = Str | +| r_regressions.py:58 | name_0 = ParameterDefinition | | r_regressions.py:61 | _dec_0 = FunctionExpr | | r_regressions.py:61 | func_0 = ScopeEntryDefinition | | r_regressions.py:61 | gv_20 = ScopeEntryDefinition | diff --git a/python/ql/test/library-tests/PointsTo/new/Definitions.expected b/python/ql/test/library-tests/PointsTo/new/Definitions.expected index ce931319089..7c7fd65c593 100644 --- a/python/ql/test/library-tests/PointsTo/new/Definitions.expected +++ b/python/ql/test/library-tests/PointsTo/new/Definitions.expected @@ -32,9 +32,7 @@ | a_simple.py:34 | Local Variable kwargs | ParameterDefinition | | a_simple.py:38 | Global Variable multi_assign_and_packing | AssignmentDefinition | | a_simple.py:38 | Local Variable a | ParameterDefinition | -| a_simple.py:38 | Local Variable b | AssignmentDefinition | | a_simple.py:38 | Local Variable b | ParameterDefinition | -| a_simple.py:38 | Local Variable c | AssignmentDefinition | | a_simple.py:38 | Local Variable c | ParameterDefinition | | a_simple.py:39 | Local Variable t | AssignmentDefinition | | a_simple.py:40 | Local Variable w | AssignmentDefinition | @@ -134,7 +132,6 @@ | b_condition.py:81 | Global Variable odasa6261 | AssignmentDefinition | | b_condition.py:81 | Local Variable bar | PhiFunction | | b_condition.py:81 | Local Variable bar | ScopeEntryDefinition | -| b_condition.py:81 | Local Variable foo | AssignmentDefinition | | b_condition.py:81 | Local Variable foo | ParameterDefinition | | b_condition.py:81 | Local Variable foo | PhiFunction | | b_condition.py:81 | Local Variable foo | PyEdgeRefinement | @@ -142,9 +139,7 @@ | b_condition.py:83 | Local Variable foo | PyEdgeRefinement | | b_condition.py:83 | Local Variable foo | ScopeEntryDefinition | | b_condition.py:87 | Global Variable split_bool1 | AssignmentDefinition | -| b_condition.py:87 | Local Variable x | AssignmentDefinition | | b_condition.py:87 | Local Variable x | ParameterDefinition | -| b_condition.py:87 | Local Variable y | AssignmentDefinition | | b_condition.py:87 | Local Variable y | ParameterDefinition | | b_condition.py:88 | Local Variable x | PyEdgeRefinement | | b_condition.py:90 | Local Variable x | PyEdgeRefinement | diff --git a/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected b/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected index 0c2bd1b4ce0..171f45410b7 100644 --- a/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected +++ b/python/ql/test/library-tests/PointsTo/new/ImpliesDataflow.expected @@ -1,5 +1,7 @@ | code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:10:1:10:9 | ControlFlowNode for type() | | code/h_classes.py:3:1:3:16 | ControlFlowNode for ClassExpr | code/h_classes.py:15:5:15:13 | ControlFlowNode for type() | +| code/l_calls.py:3:13:3:14 | ControlFlowNode for List | code/l_calls.py:4:12:4:12 | ControlFlowNode for x | +| code/l_calls.py:6:13:6:14 | ControlFlowNode for List | code/l_calls.py:7:16:7:16 | ControlFlowNode for x | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:16:16:16:18 | ControlFlowNode for cls | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:24:13:24:22 | ControlFlowNode for Attribute() | | code/l_calls.py:12:1:12:20 | ControlFlowNode for ClassExpr | code/l_calls.py:25:16:25:16 | ControlFlowNode for a | diff --git a/python/ql/test/library-tests/PointsTo/new/SSA.expected b/python/ql/test/library-tests/PointsTo/new/SSA.expected index e6ed2435dd2..9914a4eeec7 100644 --- a/python/ql/test/library-tests/PointsTo/new/SSA.expected +++ b/python/ql/test/library-tests/PointsTo/new/SSA.expected @@ -25,8 +25,8 @@ | a_simple.py:23 | with_definition_0 = FunctionExpr | Function with_definition | builtin-class function | | a_simple.py:27 | multi_loop_in_try_0 = FunctionExpr | Function multi_loop_in_try | builtin-class function | | a_simple.py:34 | f_0 = FunctionExpr | Function f | builtin-class function | -| a_simple.py:38 | b_0 = Str | 'b' | builtin-class str | -| a_simple.py:38 | c_0 = Str | 'c' | builtin-class str | +| a_simple.py:38 | b_0 = ParameterDefinition | 'b' | builtin-class str | +| a_simple.py:38 | c_0 = ParameterDefinition | 'c' | builtin-class str | | a_simple.py:38 | multi_assign_and_packing_0 = FunctionExpr | Function multi_assign_and_packing | builtin-class function | | a_simple.py:39 | t_0 = Tuple | Tuple | builtin-class tuple | | a_simple.py:40 | w_0 = Tuple | Tuple | builtin-class tuple | @@ -81,14 +81,14 @@ | b_condition.py:79 | t_3 = phi(t_1, t_2) | builtin-class object | builtin-class type | | b_condition.py:79 | t_4 = ArgumentRefinement(t_3) | builtin-class object | builtin-class type | | b_condition.py:81 | bar_2 = phi(bar_0, bar_1) | Function bar | builtin-class function | -| b_condition.py:81 | foo_0 = True | bool True | builtin-class bool | +| b_condition.py:81 | foo_0 = ParameterDefinition | bool True | builtin-class bool | | b_condition.py:81 | foo_3 = Pi(foo_0) [false] | bool True | builtin-class bool | | b_condition.py:81 | foo_4 = phi(foo_1, foo_3) | bool True | builtin-class bool | | b_condition.py:81 | odasa6261_1 = FunctionExpr | Function odasa6261 | builtin-class function | | b_condition.py:83 | bar_1 = FunctionExpr | Function bar | builtin-class function | | b_condition.py:87 | split_bool1_1 = FunctionExpr | Function split_bool1 | builtin-class function | -| b_condition.py:87 | x_0 = None | NoneType None | builtin-class NoneType | -| b_condition.py:87 | y_0 = None | NoneType None | builtin-class NoneType | +| b_condition.py:87 | x_0 = ParameterDefinition | NoneType None | builtin-class NoneType | +| b_condition.py:87 | y_0 = ParameterDefinition | NoneType None | builtin-class NoneType | | b_condition.py:90 | x_4 = Pi(x_0) [false] | NoneType None | builtin-class NoneType | | b_condition.py:90 | x_5 = SingleSuccessorGuard(x_4) [false] | NoneType None | builtin-class NoneType | | b_condition.py:90 | y_4 = Pi(y_0) [false] | NoneType None | builtin-class NoneType | @@ -140,8 +140,8 @@ | c_tests.py:68 | x_5 = phi(x_3, x_4) | int 0 | builtin-class int | | c_tests.py:69 | x_6 = Pi(x_5) [true] | builtin-class float | builtin-class type | | c_tests.py:71 | compound_0 = FunctionExpr | Function compound | builtin-class function | -| c_tests.py:71 | x_0 = IntegerLiteral | int 1 | builtin-class int | -| c_tests.py:71 | y_0 = IntegerLiteral | int 0 | builtin-class int | +| c_tests.py:71 | x_0 = ParameterDefinition | int 1 | builtin-class int | +| c_tests.py:71 | y_0 = ParameterDefinition | int 0 | builtin-class int | | c_tests.py:71 | y_5 = Pi(y_0) [false] | int 0 | builtin-class int | | c_tests.py:71 | y_6 = phi(y_4, y_5) | int 0 | builtin-class int | | c_tests.py:74 | x_2 = Pi(x_0) [true] | int 1 | builtin-class int | @@ -387,8 +387,8 @@ | m_attributes.py:0 | __name___0 = ScopeEntryDefinition | 'code.m_attributes' | builtin-class str | | m_attributes.py:3 | C_0 = ClassExpr | class C | builtin-class type | | m_attributes.py:5 | __init___0 = FunctionExpr | Function __init__ | builtin-class function | -| m_attributes.py:5 | a_0 = IntegerLiteral | int 17 | builtin-class int | -| m_attributes.py:5 | a_0 = IntegerLiteral | int 100 | builtin-class int | +| m_attributes.py:5 | a_0 = ParameterDefinition | int 17 | builtin-class int | +| m_attributes.py:5 | a_0 = ParameterDefinition | int 100 | builtin-class int | | m_attributes.py:5 | self_0 = ParameterDefinition | self | class C | | m_attributes.py:6 | self_1 = AttributeAssignment 'a'(self_0) | self | class C | | m_attributes.py:8 | foo_0 = FunctionExpr | Function foo | builtin-class function | @@ -397,7 +397,7 @@ | m_attributes.py:8 | self_0 = ParameterDefinition | self | class C | | n_nesting.py:0 | __name___0 = ScopeEntryDefinition | 'code.n_nesting' | builtin-class str | | n_nesting.py:8 | C_0 = ScopeEntryDefinition | int 1 | builtin-class int | -| n_nesting.py:8 | compile_ops_0 = True | bool True | builtin-class bool | +| n_nesting.py:8 | compile_ops_0 = ParameterDefinition | bool True | builtin-class bool | | n_nesting.py:8 | foo_0 = FunctionExpr | Function foo | builtin-class function | | n_nesting.py:9 | C_1 = CallsiteRefinement(C_0) | int 1 | builtin-class int | | n_nesting.py:10 | C_5 = ScopeEntryDefinition | int 1 | builtin-class int |