From 6113d4be9e6a3711e4afdcdc22e27cb0afb56da6 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 26 Jan 2026 15:38:25 +0000 Subject: [PATCH] Python: Fix test issues Fixes the test failures that arose from making `ExtractedArgumentNode` local. For the consistency checks, we now explicitly exclude the `ExtractedArgumentNode`s (now much more plentiful due to the overapproximation) that don't have a corresponding `getCallArg` tuple. For various queries/tests using `instanceof ArgumentNode`, we instead us `isArgumentNode`, which explicitly filters out the ones for which `isArgumentOf` doesn't hold (which, again, is the case for most of the nodes in the overapproximation). --- python/ql/consistency-queries/DataFlowConsistency.ql | 10 ++++++++++ python/ql/lib/utils/test/dataflow/MaximalFlowTest.qll | 2 +- python/ql/lib/utils/test/dataflow/callGraphConfig.qll | 2 +- .../InitCallsSubclass/InitCallsSubclassMethod.ql | 3 ++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/python/ql/consistency-queries/DataFlowConsistency.ql b/python/ql/consistency-queries/DataFlowConsistency.ql index 759db3d19a9..62bbb3062c2 100644 --- a/python/ql/consistency-queries/DataFlowConsistency.ql +++ b/python/ql/consistency-queries/DataFlowConsistency.ql @@ -26,6 +26,8 @@ private module Input implements InputSig { or // TODO: Implement post-updates for **kwargs, see tests added in https://github.com/github/codeql/pull/14936 exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat()) + or + missingArgumentCallExclude(n) } predicate reverseReadExclude(Node n) { @@ -134,6 +136,14 @@ private module Input implements InputSig { other.getNode().getScope() = f ) } + + predicate missingArgumentCallExclude(ArgumentNode arg) { + // We overapproximate the argument nodes in order to not rely on the global `getCallArg` + // predicate. + // Because of this, we must exclude the cases where we have an approximation but no actual + // argument node. + arg = getCallArgApproximation() and not getCallArg(_, _, _, arg, _) + } } import MakeConsistency diff --git a/python/ql/lib/utils/test/dataflow/MaximalFlowTest.qll b/python/ql/lib/utils/test/dataflow/MaximalFlowTest.qll index 5e9831906a4..cbd3b4c6aa5 100644 --- a/python/ql/lib/utils/test/dataflow/MaximalFlowTest.qll +++ b/python/ql/lib/utils/test/dataflow/MaximalFlowTest.qll @@ -35,7 +35,7 @@ module MaximalFlowsConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { exists(node.getLocation().getFile().getRelativePath()) and not any(CallNode c).getArg(_) = node.asCfgNode() and - not node instanceof DataFlow::ArgumentNode and + not isArgumentNode(node, _, _) and not node.asCfgNode().(NameNode).getId().matches("SINK%") and not DataFlow::localFlowStep(node, _) } diff --git a/python/ql/lib/utils/test/dataflow/callGraphConfig.qll b/python/ql/lib/utils/test/dataflow/callGraphConfig.qll index 8528396a12f..85ecb9b701d 100644 --- a/python/ql/lib/utils/test/dataflow/callGraphConfig.qll +++ b/python/ql/lib/utils/test/dataflow/callGraphConfig.qll @@ -9,7 +9,7 @@ module CallGraphConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof DataFlowPrivate::ReturnNode or - node instanceof DataFlow::ArgumentNode + DataFlowPrivate::isArgumentNode(node, _, _) } predicate isSink(DataFlow::Node node) { diff --git a/python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.ql b/python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.ql index 32eb5ffe79e..4c1b3247d96 100644 --- a/python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.ql +++ b/python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.ql @@ -15,6 +15,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.internal.DataFlowDispatch +import semmle.python.dataflow.new.internal.DataFlowPrivate predicate initSelfCallOverridden( Function init, DataFlow::Node self, DataFlow::MethodCallNode call, Function target, @@ -39,7 +40,7 @@ predicate readsFromSelf(Function method) { self.getParameter() = method.getArg(0) and DataFlow::localFlow(self, sink) | - sink instanceof DataFlow::ArgumentNode + isArgumentNode(sink, _, _) or sink = any(DataFlow::AttrRead a).getObject() )