Skip to content

Commit c0c4186

Browse files
[3.11] GH-105588: Add missing error checks to some obj2ast_* converters (GH-105839)
GH-105588: Add missing error checks to some obj2ast_* converters (GH-105589) (cherry picked from commit a4056c8) Co-authored-by: Brandt Bucher <[email protected]>
1 parent abeb589 commit c0c4186

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

Lib/test/test_ast.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import dis
44
import enum
55
import os
6+
import re
67
import sys
78
import types
89
import unittest
@@ -862,6 +863,32 @@ def test_null_bytes(self):
862863
msg="source code string cannot contain null bytes"):
863864
ast.parse("a\0b")
864865

866+
def assert_none_check(self, node: type[ast.AST], attr: str, source: str) -> None:
867+
with self.subTest(f"{node.__name__}.{attr}"):
868+
tree = ast.parse(source)
869+
found = 0
870+
for child in ast.walk(tree):
871+
if isinstance(child, node):
872+
setattr(child, attr, None)
873+
found += 1
874+
self.assertEqual(found, 1)
875+
e = re.escape(f"field '{attr}' is required for {node.__name__}")
876+
with self.assertRaisesRegex(ValueError, f"^{e}$"):
877+
compile(tree, "<test>", "exec")
878+
879+
def test_none_checks(self) -> None:
880+
tests = [
881+
(ast.alias, "name", "import spam as SPAM"),
882+
(ast.arg, "arg", "def spam(SPAM): spam"),
883+
(ast.comprehension, "target", "[spam for SPAM in spam]"),
884+
(ast.comprehension, "iter", "[spam for spam in SPAM]"),
885+
(ast.keyword, "value", "spam(**SPAM)"),
886+
(ast.match_case, "pattern", "match spam:\n case SPAM: spam"),
887+
(ast.withitem, "context_expr", "with SPAM: spam"),
888+
]
889+
for node, attr, source in tests:
890+
self.assert_none_check(node, attr, source)
891+
865892
class ASTHelpers_Test(unittest.TestCase):
866893
maxDiff = None
867894

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix an issue that could result in crashes when compiling malformed
2+
:mod:`ast` nodes.

Parser/asdl_c.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ def visitProduct(self, prod, name):
602602
args = [f.name for f in prod.fields]
603603
args.extend([a.name for a in prod.attributes])
604604
self.emit("*out = %s(%s);" % (ast_func_name(name), self.buildArgs(args)), 1)
605+
self.emit("if (*out == NULL) goto failed;", 1)
605606
self.emit("return 0;", 1)
606607
self.emit("failed:", 0)
607608
self.emit("Py_XDECREF(tmp);", 1)

Python/Python-ast.c

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)