Skip to content

Commit 0de4e08

Browse files
authored
gh-146250: Fix memory leak in re-initialization of SyntaxError (#146251)
1 parent 5466f57 commit 0de4e08

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

Lib/test/test_exceptions.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,30 @@ def test_incorrect_constructor(self):
25612561
args = ("bad.py", 1, 2, "abcdefg", 1)
25622562
self.assertRaises(TypeError, SyntaxError, "bad bad", args)
25632563

2564+
def test_syntax_error_memory_leak(self):
2565+
# gh-146250: memory leak with re-initialization of SyntaxError
2566+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2567+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4))
2568+
self.assertEqual(e.msg, "new_msg")
2569+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4)))
2570+
self.assertEqual(e.filename, "new_file.py")
2571+
self.assertEqual(e.lineno, 2)
2572+
self.assertEqual(e.offset, 3)
2573+
self.assertEqual(e.text, "new_txt")
2574+
self.assertEqual(e.end_lineno, 3)
2575+
self.assertEqual(e.end_offset, 4)
2576+
2577+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2578+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt"))
2579+
self.assertEqual(e.msg, "new_msg")
2580+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt")))
2581+
self.assertEqual(e.filename, "new_file.py")
2582+
self.assertEqual(e.lineno, 2)
2583+
self.assertEqual(e.offset, 3)
2584+
self.assertEqual(e.text, "new_txt")
2585+
self.assertIsNone(e.end_lineno)
2586+
self.assertIsNone(e.end_offset)
2587+
25642588

25652589
class TestInvalidExceptionMatcher(unittest.TestCase):
25662590
def test_except_star_invalid_exception_type(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a memory leak in :exc:`SyntaxError` when re-initializing it.

Objects/exceptions.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,23 +2802,25 @@ SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
28022802
return -1;
28032803
}
28042804

2805-
self->end_lineno = NULL;
2806-
self->end_offset = NULL;
2805+
PyObject *filename, *lineno, *offset, *text;
2806+
PyObject *end_lineno = NULL;
2807+
PyObject *end_offset = NULL;
2808+
PyObject *metadata = NULL;
28072809
if (!PyArg_ParseTuple(info, "OOOO|OOO",
2808-
&self->filename, &self->lineno,
2809-
&self->offset, &self->text,
2810-
&self->end_lineno, &self->end_offset, &self->metadata)) {
2810+
&filename, &lineno,
2811+
&offset, &text,
2812+
&end_lineno, &end_offset, &metadata)) {
28112813
Py_DECREF(info);
28122814
return -1;
28132815
}
28142816

2815-
Py_INCREF(self->filename);
2816-
Py_INCREF(self->lineno);
2817-
Py_INCREF(self->offset);
2818-
Py_INCREF(self->text);
2819-
Py_XINCREF(self->end_lineno);
2820-
Py_XINCREF(self->end_offset);
2821-
Py_XINCREF(self->metadata);
2817+
Py_XSETREF(self->filename, Py_NewRef(filename));
2818+
Py_XSETREF(self->lineno, Py_NewRef(lineno));
2819+
Py_XSETREF(self->offset, Py_NewRef(offset));
2820+
Py_XSETREF(self->text, Py_NewRef(text));
2821+
Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2822+
Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
2823+
Py_XSETREF(self->metadata, Py_XNewRef(metadata));
28222824
Py_DECREF(info);
28232825

28242826
if (self->end_lineno != NULL && self->end_offset == NULL) {

0 commit comments

Comments
 (0)