Skip to content

Commit 7a83644

Browse files
sobolevnvstinner
andauthored
[3.13] gh-130775: Allow negative locations in ast (GH-130795) (#132243)
(cherry picked from commit bc5233b) Co-authored-by: Victor Stinner <[email protected]>
1 parent ed28f2f commit 7a83644

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

Lib/test/test_ast/test_ast.py

+20
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ def test_compilation_of_ast_nodes_with_default_end_position_values(self):
204204
# Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
205205
compile(tree, "<string>", "exec")
206206

207+
def test_negative_locations_for_compile(self):
208+
# See https://github.com/python/cpython/issues/130775
209+
alias = ast.alias(name='traceback', lineno=0, col_offset=0)
210+
for attrs in (
211+
{'lineno': -2, 'col_offset': 0},
212+
{'lineno': 0, 'col_offset': -2},
213+
{'lineno': 0, 'col_offset': -2, 'end_col_offset': -2},
214+
{'lineno': -2, 'end_lineno': -2, 'col_offset': 0},
215+
):
216+
with self.subTest(attrs=attrs):
217+
tree = ast.Module(body=[
218+
ast.Import(names=[alias], **attrs)
219+
], type_ignores=[])
220+
221+
# It used to crash on this step:
222+
compile(tree, "<string>", "exec")
223+
224+
# This also must not crash:
225+
ast.parse(tree, optimize=2)
226+
207227
def test_slice(self):
208228
slc = ast.parse("x[::]").body[0].value.slice
209229
self.assertIsNone(slc.upper)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not crash on negative ``column`` and ``end_column`` in :mod:`ast` locations.

Python/assemble.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -290,17 +290,15 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
290290
assert(len > THEORETICAL_MAX_ENTRY_SIZE);
291291
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
292292
}
293-
if (loc.lineno < 0) {
293+
if (loc.lineno == NO_LOCATION.lineno) {
294294
write_location_info_none(a, isize);
295295
return SUCCESS;
296296
}
297297
int line_delta = loc.lineno - a->a_lineno;
298298
int column = loc.col_offset;
299299
int end_column = loc.end_col_offset;
300-
assert(column >= -1);
301-
assert(end_column >= -1);
302300
if (column < 0 || end_column < 0) {
303-
if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
301+
if (loc.end_lineno == loc.lineno || loc.end_lineno < 0) {
304302
write_location_info_no_column(a, isize, line_delta);
305303
a->a_lineno = loc.lineno;
306304
return SUCCESS;

0 commit comments

Comments
 (0)