diff --git a/java/ql/test/library-tests/dataflow/deduplicate-path-graph/test.ql b/java/ql/test/library-tests/dataflow/deduplicate-path-graph/test.ql index efe8dabc024..6d7e7c7b95d 100644 --- a/java/ql/test/library-tests/dataflow/deduplicate-path-graph/test.ql +++ b/java/ql/test/library-tests/dataflow/deduplicate-path-graph/test.ql @@ -47,9 +47,10 @@ predicate reachableFromPropagate(Graph::PathNode node, string state, boolean cal node.getNode().asExpr() = propagateCall(state) and call = false or exists(Graph::PathNode prev | reachableFromPropagate(prev, state, call) | - Graph::edges(prev, node, _, _) + Graph::edges(prev, node, _, _) and + not Graph::subpaths(prev, node, _, _) // argument-passing edges are handled separately or - Graph::subpaths(prev, _, _, node) // arg -> out + Graph::subpaths(prev, _, _, node) // arg -> out (should be included in 'edges' but handle the case here for clarity) ) or exists(Graph::PathNode prev | diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 0c39f8873c1..701b50a4ec1 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -935,11 +935,15 @@ module DataFlowMake Lang> { ) } - /** Gets a successor of `node` including subpath flow-through. */ + /** Gets a successor of `node`, including subpath flow-through, but not enter or exit subpath steps. */ InputPathNode stepEx(InputPathNode node) { - step(node, result, _, _) + step(node, result, _, _) and + not result = enterSubpathStep(node) and + not result = exitSubpathStep(node) or - subpathStep(node, _, _, result) // assuming the input is pruned properly, all subpaths have flow-through + // Assuming the input is pruned properly, all subpaths have flow-through. + // This step should be in 'step' as well, but include it here for clarity as we rely on it. + subpathStep(node, _, _, result) } InputPathNode enterSubpathStep(InputPathNode node) { subpathStep(node, result, _, _) }