From 79101edb03b7381b514126c68acabfcbbba2f842 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 13 Sep 2023 09:00:15 -0700 Subject: gh-109351: Fix crash when compiling AST with invalid NamedExpr (#109352) --- Lib/test/test_compile.py | 27 ++++++++++++++++++++++ .../2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst | 2 ++ Python/ast.c | 5 ++++ 3 files changed, 34 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index a8a519f..fa74455 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -443,6 +443,33 @@ class TestSpecifics(unittest.TestCase): self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) self.assertIn("__package__", A.f.__code__.co_varnames) + def test_compile_invalid_namedexpr(self): + # gh-109351 + m = ast.Module( + body=[ + ast.Expr( + value=ast.ListComp( + elt=ast.NamedExpr( + target=ast.Constant(value=1), + value=ast.Constant(value=3), + ), + generators=[ + ast.comprehension( + target=ast.Name(id="x", ctx=ast.Store()), + iter=ast.Name(id="y", ctx=ast.Load()), + ifs=[], + is_async=0, + ) + ], + ) + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_compile_ast(self): fname = __file__ if fname.lower().endswith('pyc'): diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst new file mode 100644 index 0000000..23b81c1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst @@ -0,0 +1,2 @@ +Fix crash when compiling an invalid AST involving a named (walrus) +expression. diff --git a/Python/ast.c b/Python/ast.c index 21cb38f..a230c7e 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -381,6 +381,11 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); break; case NamedExpr_kind: + if (exp->v.NamedExpr.target->kind != Name_kind) { + PyErr_SetString(PyExc_TypeError, + "NamedExpr target must be a Name"); + return 0; + } ret = validate_expr(state, exp->v.NamedExpr.value, Load); break; /* This last case doesn't have any checking. */ -- cgit v0.12