From cedec19be81e6bd153678bfb28c8e217af8bda58 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 11 Jan 2022 16:30:39 +0000 Subject: [PATCH] bpo-46339: Fix crash in the parser when computing error text for multi-line f-strings (GH-30529) Automerge-Triggered-By: GH:pablogsal --- Lib/test/test_exceptions.py | 6 ++++++ .../2022-01-11-11-50-19.bpo-46339.OVumDZ.rst | 3 +++ Parser/pegen_errors.c | 11 +++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index e4d685f4154..531b9c92dea 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -280,6 +280,12 @@ def baz(): } \"\"\" }'''""", 5, 17) + check('''f""" + + + { + 6 + 0="""''', 5, 13) # Errors thrown by symtable.c check('x = [(yield i) for i in range(3)]', 1, 7) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst new file mode 100644 index 00000000000..cd04f060826 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst @@ -0,0 +1,3 @@ +Fix a crash in the parser when retrieving the error text for multi-line +f-strings expressions that do not start in the first line of the string. +Patch by Pablo Galindo diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index f07d9d8a34d..bffae8532ca 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -250,8 +250,15 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno) char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; assert(cur_line != NULL); - for (int i = 0; i < lineno - 1; i++) { - cur_line = strchr(cur_line, '\n') + 1; + Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; + + for (int i = 0; i < relative_lineno - 1; i++) { + char *new_line = strchr(cur_line, '\n') + 1; + assert(new_line != NULL && new_line < p->tok->inp); + if (new_line == NULL || new_line >= p->tok->inp) { + break; + } + cur_line = new_line; } char *next_newline;