Skip to content

Commit a4056c8

Browse files
authored
GH-105588: Add missing error checks to some obj2ast_* converters (GH-105589)
1 parent 3af2dc7 commit a4056c8

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

Lib/test/test_ast.py

+27
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 textwrap
89
import types
@@ -1110,6 +1111,32 @@ def test_null_bytes(self):
11101111
msg="source code string cannot contain null bytes"):
11111112
ast.parse("a\0b")
11121113

1114+
def assert_none_check(self, node: type[ast.AST], attr: str, source: str) -> None:
1115+
with self.subTest(f"{node.__name__}.{attr}"):
1116+
tree = ast.parse(source)
1117+
found = 0
1118+
for child in ast.walk(tree):
1119+
if isinstance(child, node):
1120+
setattr(child, attr, None)
1121+
found += 1
1122+
self.assertEqual(found, 1)
1123+
e = re.escape(f"field '{attr}' is required for {node.__name__}")
1124+
with self.assertRaisesRegex(ValueError, f"^{e}$"):
1125+
compile(tree, "<test>", "exec")
1126+
1127+
def test_none_checks(self) -> None:
1128+
tests = [
1129+
(ast.alias, "name", "import spam as SPAM"),
1130+
(ast.arg, "arg", "def spam(SPAM): spam"),
1131+
(ast.comprehension, "target", "[spam for SPAM in spam]"),
1132+
(ast.comprehension, "iter", "[spam for spam in SPAM]"),
1133+
(ast.keyword, "value", "spam(**SPAM)"),
1134+
(ast.match_case, "pattern", "match spam:\n case SPAM: spam"),
1135+
(ast.withitem, "context_expr", "with SPAM: spam"),
1136+
]
1137+
for node, attr, source in tests:
1138+
self.assert_none_check(node, attr, source)
1139+
11131140
class ASTHelpers_Test(unittest.TestCase):
11141141
maxDiff = None
11151142

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

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

Python/Python-ast.c

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)