From 4c8f7775cc7f9da76ec13d0e61f0471c23db66a5 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 7 Apr 2025 19:35:17 +0300 Subject: [PATCH 1/2] [3.12] gh-130775: Allow negative locations in `ast` (GH-130795) (cherry picked from commit bc5233b6a5cdd8f77a4737ce317f94110869c082) Co-authored-by: sobolevn Co-authored-by: Victor Stinner --- Lib/test/test_ast/test_ast.py | 20 +++++++++++++++++++ ...-03-03-20-02-45.gh-issue-130775.fEM6T-.rst | 1 + Python/assemble.c | 6 ++---- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index f07e2d027b1624..9b4415be06b5e8 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -160,6 +160,26 @@ def test_compilation_of_ast_nodes_with_default_end_position_values(self): # Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode. compile(tree, "", "exec") + def test_negative_locations_for_compile(self): + # See https://github.com/python/cpython/issues/130775 + alias = ast.alias(name='traceback', lineno=0, col_offset=0) + for attrs in ( + {'lineno': -2, 'col_offset': 0}, + {'lineno': 0, 'col_offset': -2}, + {'lineno': 0, 'col_offset': -2, 'end_col_offset': -2}, + {'lineno': -2, 'end_lineno': -2, 'col_offset': 0}, + ): + with self.subTest(attrs=attrs): + tree = ast.Module(body=[ + ast.Import(names=[alias], **attrs) + ], type_ignores=[]) + + # It used to crash on this step: + compile(tree, "", "exec") + + # This also must not crash: + ast.parse(tree, optimize=2) + def test_slice(self): slc = ast.parse("x[::]").body[0].value.slice self.assertIsNone(slc.upper) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst new file mode 100644 index 00000000000000..53408cd427596c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst @@ -0,0 +1 @@ +Do not crash on negative ``column`` and ``end_column`` in :mod:`ast` locations. diff --git a/Python/assemble.c b/Python/assemble.c index 4aa922848f23aa..6a68482c36e01b 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -268,17 +268,15 @@ write_location_info_entry(struct assembler* a, location loc, int isize) assert(len > THEORETICAL_MAX_ENTRY_SIZE); RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2)); } - if (loc.lineno < 0) { + if (loc.lineno == NO_LOCATION.lineno) { write_location_info_none(a, isize); return SUCCESS; } int line_delta = loc.lineno - a->a_lineno; int column = loc.col_offset; int end_column = loc.end_col_offset; - assert(column >= -1); - assert(end_column >= -1); if (column < 0 || end_column < 0) { - if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) { + if (loc.end_lineno == loc.lineno || loc.end_lineno < 0) { write_location_info_no_column(a, isize, line_delta); a->a_lineno = loc.lineno; return SUCCESS; From cc4558c9103fbd6b3ed487e695169f201608dfaf Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 8 Apr 2025 13:02:20 +0300 Subject: [PATCH 2/2] Update test_ast.py --- Lib/test/test_ast/test_ast.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 9b4415be06b5e8..3f952a2b085029 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -177,9 +177,6 @@ def test_negative_locations_for_compile(self): # It used to crash on this step: compile(tree, "", "exec") - # This also must not crash: - ast.parse(tree, optimize=2) - def test_slice(self): slc = ast.parse("x[::]").body[0].value.slice self.assertIsNone(slc.upper)