diff --git a/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.expected b/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.expected new file mode 100644 index 000000000000..5834c35bd638 --- /dev/null +++ b/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.expected @@ -0,0 +1,17 @@ +consistencyOverview +siblingsWithSameIndexInDefaultCfg +deadEnd +nonUniqueEnclosingCallable +nonUniqueInConditionalContext +nonLocalStep +ambiguousAdditionalNode +invalidAbruptCompletionOrigin +missingInNodeForPostOrInOrder +multipleSuccessors +multipleConditionalSuccessorKinds +directAndConditionalSuccessors +selfLoop +bodyPartNonOverlap +parameterNonOverlap +parameterEnclosingCallable +#select diff --git a/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.ql b/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.ql new file mode 100644 index 000000000000..91c6a93e025a --- /dev/null +++ b/csharp/ql/test/library-tests/controlflow/graph/InvalidAbruptCompletionOrigin.ql @@ -0,0 +1,6 @@ +import csharp +import ControlFlow::Consistency + +from int results +where consistencyOverview("invalidAbruptCompletionOrigin", results) +select results diff --git a/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.expected b/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.expected new file mode 100644 index 000000000000..5834c35bd638 --- /dev/null +++ b/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.expected @@ -0,0 +1,17 @@ +consistencyOverview +siblingsWithSameIndexInDefaultCfg +deadEnd +nonUniqueEnclosingCallable +nonUniqueInConditionalContext +nonLocalStep +ambiguousAdditionalNode +invalidAbruptCompletionOrigin +missingInNodeForPostOrInOrder +multipleSuccessors +multipleConditionalSuccessorKinds +directAndConditionalSuccessors +selfLoop +bodyPartNonOverlap +parameterNonOverlap +parameterEnclosingCallable +#select diff --git a/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.ql b/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.ql new file mode 100644 index 000000000000..0e4aa51f72f0 --- /dev/null +++ b/java/ql/test/library-tests/controlflow/basic/InvalidAbruptCompletionOrigin.ql @@ -0,0 +1,6 @@ +import java +import ControlFlow::Consistency + +from int results +where consistencyOverview("invalidAbruptCompletionOrigin", results) +select results diff --git a/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.expected b/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.expected new file mode 100644 index 000000000000..5834c35bd638 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.expected @@ -0,0 +1,17 @@ +consistencyOverview +siblingsWithSameIndexInDefaultCfg +deadEnd +nonUniqueEnclosingCallable +nonUniqueInConditionalContext +nonLocalStep +ambiguousAdditionalNode +invalidAbruptCompletionOrigin +missingInNodeForPostOrInOrder +multipleSuccessors +multipleConditionalSuccessorKinds +directAndConditionalSuccessors +selfLoop +bodyPartNonOverlap +parameterNonOverlap +parameterEnclosingCallable +#select diff --git a/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.ql b/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.ql new file mode 100644 index 000000000000..2d3cf71dffe9 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/successors/InvalidAbruptCompletionOrigin.ql @@ -0,0 +1,6 @@ +import semmle.python.controlflow.internal.AstNodeImpl +import ControlFlow::Consistency + +from int results +where consistencyOverview("invalidAbruptCompletionOrigin", results) +select results diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 042aa29fc421..ccf093cfa76d 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -2257,6 +2257,12 @@ module Make0 Ast> { query = "missingInNodeForPostOrInOrder" and results = strictcount(AstNode ast | missingInNodeForPostOrInOrder(ast)) or + query = "invalidAbruptCompletionOrigin" and + results = + strictcount(AstNode ast, PreControlFlowNode node | + invalidAbruptCompletionOrigin(ast, node) + ) + or query = "multipleSuccessors" and results = strictcount(ControlFlowNode node, SuccessorType t, ControlFlowNode successor | @@ -2341,6 +2347,16 @@ module Make0 Ast> { 1 < strictcount(NormalSuccessor t | additionalNode(n, tag, t)) } + /** + * Holds if the language-specific CFG input supplies an abrupt completion for `ast` whose + * origin `node` does not belong to `ast`. + */ + query predicate invalidAbruptCompletionOrigin(AstNode ast, PreControlFlowNode node) { + Input2::beginAbruptCompletion(ast, node, _, _) and + not node.isIn(ast) and + not node.isAdditional(ast, _) + } + /** * Holds if the "in" node is unreachable for a post-or-in-order AST node. *