From 14fa2556e46d42f1c81adfb17de23b97c7b06f08 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 11 Jun 2026 15:26:46 +0100 Subject: [PATCH] gh-151238: Check for `_get_resized_exprs` failure in `_PyPegen_{joined,template}_str` (GH-151259) (cherry picked from commit 4b44b1e1fd654f3a3fefb02ae7fb26456fe33dc3) Co-authored-by: Stan Ulbrych --- Lib/test/test_fstring.py | 11 +++++++++++ .../2026-06-10-15-19-58.gh-issue-151238.C9Wu4x.rst | 2 ++ Parser/action_helpers.c | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-19-58.gh-issue-151238.C9Wu4x.rst diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 05d0cbd2445c4cb..5cc02c30ec2ba33 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -593,6 +593,17 @@ def test_compile_time_concat_errors(self): r"""b'' f''""", ]) + def test_concat_decode_failure_does_not_crash(self): + script = r''' +import builtins +builtins.__import__ = builtins # Breaks warning machinery so _get_resized_exprs returns NULL +try: + compile('"x"f"\]"b""', '', 'exec') +except Exception: + pass +''' + assert_python_ok('-c', script) + def test_literal(self): self.assertEqual(f'', '') self.assertEqual(f'a', 'a') diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-19-58.gh-issue-151238.C9Wu4x.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-19-58.gh-issue-151238.C9Wu4x.rst new file mode 100644 index 000000000000000..fe7519fb4878952 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-19-58.gh-issue-151238.C9Wu4x.rst @@ -0,0 +1,2 @@ +Fix a crash when compiling a concatenated f-string or t-string if an error +occurs when processing one of it's parts. diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index a24744d77eabb95..a0657708fa8d9b5 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -1387,6 +1387,9 @@ expr_ty _PyPegen_template_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b) { asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, TSTRING); + if (resized_exprs == NULL) { + return NULL; + } return _PyAST_TemplateStr(resized_exprs, a->lineno, a->col_offset, b->end_lineno, b->end_col_offset, p->arena); @@ -1396,6 +1399,9 @@ expr_ty _PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) { asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, FSTRING); + if (resized_exprs == NULL) { + return NULL; + } return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset, b->end_lineno, b->end_col_offset, p->arena);