]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-130775: Allow negative locations in `ast` (GH-130795) (#132260)
authorsobolevn <mail@sobolevn.me>
Tue, 8 Apr 2025 10:19:23 +0000 (13:19 +0300)
committerGitHub <noreply@github.com>
Tue, 8 Apr 2025 10:19:23 +0000 (10:19 +0000)
(cherry picked from commit bc5233b6a5cdd8f77a4737ce317f94110869c082)

Co-authored-by: sobolevn <mail@sobolevn.me>
Co-authored-by: Victor Stinner <vstinner@python.org>
Lib/test/test_ast/test_ast.py
Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst [new file with mode: 0644]
Python/assemble.c

index f07e2d027b1624b7a758f189d1bba65e56bd2abd..3f952a2b085029bb40f04d4adc75b15c79c059ad 100644 (file)
@@ -160,6 +160,23 @@ class AST_Tests(unittest.TestCase):
         # Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
         compile(tree, "<string>", "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, "<string>", "exec")
+
     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 (file)
index 0000000..53408cd
--- /dev/null
@@ -0,0 +1 @@
+Do not crash on negative ``column`` and ``end_column`` in :mod:`ast` locations.
index 4aa922848f23aa53e975a9fb2f4e9db8ca7871f6..6a68482c36e01b71d23d27ea6d73c6e4bf73b644 100644 (file)
@@ -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;