Skip to content

Commit dea1506

Browse files
committed
Python: Restrict the set of throwing exceptions
Technically all unary and binary expressions can throw if they dispatch to dunder implementations (such as __neq__). But we omit these edges to obtain a more useful CFG; the cases where user code catches these exceptions are probably rare.
1 parent 3e0e859 commit dea1506

1 file changed

Lines changed: 8 additions & 9 deletions

File tree

python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,12 +1635,15 @@ private module Input implements InputSig1, InputSig2 {
16351635
* its normal evaluation (not via an explicit `raise`/`assert`, which are
16361636
* modeled separately).
16371637
*
1638-
* The set mirrors what the legacy CFG used to flag implicitly: function
1638+
* `TypeError` is intentionally excluded along with exceptions thrown by dunder
1639+
* implementations to avoid cluttering the CFG; we expect user code to catch
1640+
* these only rarely.
1641+
*
1642+
* Otherwise, the set mirrors what the legacy CFG used to flag implicitly: function
16391643
* calls (anything can raise), attribute access (`AttributeError`),
1640-
* subscript access (`IndexError`/`KeyError`/`TypeError`), arithmetic and
1641-
* comparison operators (`TypeError`/`ZeroDivisionError`), imports
1644+
* subscript access (`IndexError`/`KeyError`), division (`ZeroDivisionError`), imports
16421645
* (`ImportError`/`ModuleNotFoundError`), and generator/coroutine
1643-
* suspension points (`await`/`yield`/`yield from`).
1646+
* suspension points (`await`/`yield`/`yield from` throwing `CancelledError` or `GeneratorExit`).
16441647
*
16451648
* Bare `Name` reads are intentionally excluded — modeling every name
16461649
* read as `mayThrow` would explode CFG edge count for negligible
@@ -1654,11 +1657,7 @@ private module Input implements InputSig1, InputSig2 {
16541657
or
16551658
e instanceof Py::Subscript
16561659
or
1657-
e instanceof Py::BinaryExpr
1658-
or
1659-
e instanceof Py::UnaryExpr
1660-
or
1661-
e instanceof Py::Compare
1660+
e instanceof Py::BinaryExpr and e.(Py::BinaryExpr).getOp() instanceof Py::Div
16621661
or
16631662
e instanceof Py::ImportExpr
16641663
or

0 commit comments

Comments
 (0)