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 29504b6aa38..1569a62b2e9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -292,7 +292,12 @@ module EssaFlow { // nodeFrom is `f(42)`, cfg node // nodeTo is `x`, essa var nodeFrom.(CfgNode).getNode() = - nodeTo.(EssaNode).getVar().getDefinition().(AssignmentDefinition).getValue() + 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() or // With definition // `with f(42) as x:` @@ -463,6 +468,13 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) { or // Setting the possible values of the variable at the end of import time nodeFrom = nodeTo.(ModuleVariableNode).getADefiningWrite() + or + // a parameter with a default value, since the parameter will be in the scope of the + // 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() } /**