mirror of
https://github.com/github/codeql.git
synced 2026-06-19 11:51:08 +02:00
The new CFG previously only emitted exception edges for explicit `raise` and `assert` statements. As a result, code that became reachable only via the exception path of an arbitrary expression (e.g., the body of an `except` handler following a try-body whose `call()` could raise) was classified as dead, breaking analyses like StackTraceExposure, FileNotAlwaysClosed, ExceptionInfo, UseOfExit, and CatchingBaseException. This commit adds a `mayThrow` predicate over expressions that are known sources of implicit exceptions in Python (calls, attribute access, subscripts, arithmetic/comparison operators, imports, await/yield/yield from) plus `from m import *` at the statement level, and routes them through the shared CFG's `beginAbruptCompletion(_, _, ExceptionSuccessor, always=false)` hook. The set of exception sources is restricted to nodes that are syntactically inside a `try`/`with` statement in the same scope. This mirrors Java's `ControlFlowGraph::mayThrow`, which only emits exception edges where local handling can observe them — outside such contexts, the edges add CFG complexity (weakening BarrierGuard precision and breaking SSA continuity around augmented assignments and subscript stores) without analysis benefit, since exceptions just propagate to the function exit anyway. Net effect on the test suite: ~100 alerts restored across the exception- related query tests (StackTraceExposure +29, ExceptionInfo +17, FileNotAlwaysClosed +52, UseOfExit +1, CatchingBaseException restored) with no precision regressions. Affected `.expected` files and the regression-guard `dead_under_no_raise.py` are updated accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
34 lines
2.9 KiB
Plaintext
34 lines
2.9 KiB
Plaintext
edges
|
|
| test.py:23:25:23:25 | e | test.py:24:16:24:16 | e | provenance | |
|
|
| test.py:31:25:31:25 | e | test.py:32:16:32:16 | e | provenance | |
|
|
| test.py:32:16:32:16 | e | test.py:32:16:32:30 | After Attribute | provenance | Config |
|
|
| test.py:49:9:49:11 | err | test.py:50:29:50:31 | err | provenance | |
|
|
| test.py:49:15:49:36 | After Attribute() | test.py:49:9:49:11 | err | provenance | |
|
|
| test.py:50:29:50:31 | err | test.py:50:16:50:32 | After format_error() | provenance | |
|
|
| test.py:50:29:50:31 | err | test.py:52:18:52:20 | msg | provenance | |
|
|
| test.py:52:18:52:20 | msg | test.py:53:12:53:27 | After BinaryExpr | provenance | |
|
|
| test.py:65:25:65:25 | e | test.py:66:24:66:40 | After Dict | provenance | |
|
|
nodes
|
|
| test.py:16:16:16:37 | After Attribute() | semmle.label | After Attribute() |
|
|
| test.py:23:25:23:25 | e | semmle.label | e |
|
|
| test.py:24:16:24:16 | e | semmle.label | e |
|
|
| test.py:31:25:31:25 | e | semmle.label | e |
|
|
| test.py:32:16:32:16 | e | semmle.label | e |
|
|
| test.py:32:16:32:30 | After Attribute | semmle.label | After Attribute |
|
|
| test.py:49:9:49:11 | err | semmle.label | err |
|
|
| test.py:49:15:49:36 | After Attribute() | semmle.label | After Attribute() |
|
|
| test.py:50:16:50:32 | After format_error() | semmle.label | After format_error() |
|
|
| test.py:50:29:50:31 | err | semmle.label | err |
|
|
| test.py:52:18:52:20 | msg | semmle.label | msg |
|
|
| test.py:53:12:53:27 | After BinaryExpr | semmle.label | After BinaryExpr |
|
|
| test.py:65:25:65:25 | e | semmle.label | e |
|
|
| test.py:66:24:66:40 | After Dict | semmle.label | After Dict |
|
|
subpaths
|
|
| test.py:50:29:50:31 | err | test.py:52:18:52:20 | msg | test.py:53:12:53:27 | After BinaryExpr | test.py:50:16:50:32 | After format_error() |
|
|
#select
|
|
| test.py:16:16:16:37 | After Attribute() | test.py:16:16:16:37 | After Attribute() | test.py:16:16:16:37 | After Attribute() | $@ flows to this location and may be exposed to an external user. | test.py:16:16:16:37 | After Attribute() | Stack trace information |
|
|
| test.py:24:16:24:16 | e | test.py:23:25:23:25 | e | test.py:24:16:24:16 | e | $@ flows to this location and may be exposed to an external user. | test.py:23:25:23:25 | e | Stack trace information |
|
|
| test.py:32:16:32:30 | After Attribute | test.py:31:25:31:25 | e | test.py:32:16:32:30 | After Attribute | $@ flows to this location and may be exposed to an external user. | test.py:31:25:31:25 | e | Stack trace information |
|
|
| test.py:50:16:50:32 | After format_error() | test.py:49:15:49:36 | After Attribute() | test.py:50:16:50:32 | After format_error() | $@ flows to this location and may be exposed to an external user. | test.py:49:15:49:36 | After Attribute() | Stack trace information |
|
|
| test.py:66:24:66:40 | After Dict | test.py:65:25:65:25 | e | test.py:66:24:66:40 | After Dict | $@ flows to this location and may be exposed to an external user. | test.py:65:25:65:25 | e | Stack trace information |
|