Skip to content

Commit

Permalink
[3.12] GH-105588: Add missing error checks to some obj2ast_* converte…
Browse files Browse the repository at this point in the history
…rs (GH-105838)

GH-105588: Add missing error checks to some obj2ast_* converters (GH-105589)
(cherry picked from commit a4056c8)

Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
  • Loading branch information
miss-islington and brandtbucher committed Jun 15, 2023
1 parent e9cf5a3 commit 0add516
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Lib/test/test_ast.py
Expand Up @@ -3,6 +3,7 @@
import dis
import enum
import os
import re
import sys
import textwrap
import types
Expand Down Expand Up @@ -1110,6 +1111,32 @@ def test_null_bytes(self):
msg="source code string cannot contain null bytes"):
ast.parse("a\0b")

def assert_none_check(self, node: type[ast.AST], attr: str, source: str) -> None:
with self.subTest(f"{node.__name__}.{attr}"):
tree = ast.parse(source)
found = 0
for child in ast.walk(tree):
if isinstance(child, node):
setattr(child, attr, None)
found += 1
self.assertEqual(found, 1)
e = re.escape(f"field '{attr}' is required for {node.__name__}")
with self.assertRaisesRegex(ValueError, f"^{e}$"):
compile(tree, "<test>", "exec")

def test_none_checks(self) -> None:
tests = [
(ast.alias, "name", "import spam as SPAM"),
(ast.arg, "arg", "def spam(SPAM): spam"),
(ast.comprehension, "target", "[spam for SPAM in spam]"),
(ast.comprehension, "iter", "[spam for spam in SPAM]"),
(ast.keyword, "value", "spam(**SPAM)"),
(ast.match_case, "pattern", "match spam:\n case SPAM: spam"),
(ast.withitem, "context_expr", "with SPAM: spam"),
]
for node, attr, source in tests:
self.assert_none_check(node, attr, source)

class ASTHelpers_Test(unittest.TestCase):
maxDiff = None

Expand Down
@@ -0,0 +1,2 @@
Fix an issue that could result in crashes when compiling malformed
:mod:`ast` nodes.
1 change: 1 addition & 0 deletions Parser/asdl_c.py
Expand Up @@ -601,6 +601,7 @@ def visitProduct(self, prod, name):
args = [f.name for f in prod.fields]
args.extend([a.name for a in prod.attributes])
self.emit("*out = %s(%s);" % (ast_func_name(name), self.buildArgs(args)), 1)
self.emit("if (*out == NULL) goto failed;", 1)
self.emit("return 0;", 1)
self.emit("failed:", 0)
self.emit("Py_XDECREF(tmp);", 1)
Expand Down
7 changes: 7 additions & 0 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0add516

Please sign in to comment.