Skip to content

Commit 3c434f7

Browse files
[3.14] gh-146250: Fix memory leak in re-initialization of SyntaxError (GH-146251) (#146517)
Co-authored-by: Brij Kapadia <97006829+bkap123@users.noreply.github.com>
1 parent ec11485 commit 3c434f7

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
@@ -2508,6 +2508,30 @@ def test_incorrect_constructor(self):
25082508
args = ("bad.py", 1, 2, "abcdefg", 1)
25092509
self.assertRaises(TypeError, SyntaxError, "bad bad", args)
25102510

2511+
def test_syntax_error_memory_leak(self):
2512+
# gh-146250: memory leak with re-initialization of SyntaxError
2513+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2514+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4))
2515+
self.assertEqual(e.msg, "new_msg")
2516+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4)))
2517+
self.assertEqual(e.filename, "new_file.py")
2518+
self.assertEqual(e.lineno, 2)
2519+
self.assertEqual(e.offset, 3)
2520+
self.assertEqual(e.text, "new_txt")
2521+
self.assertEqual(e.end_lineno, 3)
2522+
self.assertEqual(e.end_offset, 4)
2523+
2524+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2525+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt"))
2526+
self.assertEqual(e.msg, "new_msg")
2527+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt")))
2528+
self.assertEqual(e.filename, "new_file.py")
2529+
self.assertEqual(e.lineno, 2)
2530+
self.assertEqual(e.offset, 3)
2531+
self.assertEqual(e.text, "new_txt")
2532+
self.assertIsNone(e.end_lineno)
2533+
self.assertIsNone(e.end_offset)
2534+
25112535

25122536
class TestInvalidExceptionMatcher(unittest.TestCase):
25132537
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
@@ -2729,23 +2729,25 @@ SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
27292729
return -1;
27302730
}
27312731

2732-
self->end_lineno = NULL;
2733-
self->end_offset = NULL;
2732+
PyObject *filename, *lineno, *offset, *text;
2733+
PyObject *end_lineno = NULL;
2734+
PyObject *end_offset = NULL;
2735+
PyObject *metadata = NULL;
27342736
if (!PyArg_ParseTuple(info, "OOOO|OOO",
2735-
&self->filename, &self->lineno,
2736-
&self->offset, &self->text,
2737-
&self->end_lineno, &self->end_offset, &self->metadata)) {
2737+
&filename, &lineno,
2738+
&offset, &text,
2739+
&end_lineno, &end_offset, &metadata)) {
27382740
Py_DECREF(info);
27392741
return -1;
27402742
}
27412743

2742-
Py_INCREF(self->filename);
2743-
Py_INCREF(self->lineno);
2744-
Py_INCREF(self->offset);
2745-
Py_INCREF(self->text);
2746-
Py_XINCREF(self->end_lineno);
2747-
Py_XINCREF(self->end_offset);
2748-
Py_XINCREF(self->metadata);
2744+
Py_XSETREF(self->filename, Py_NewRef(filename));
2745+
Py_XSETREF(self->lineno, Py_NewRef(lineno));
2746+
Py_XSETREF(self->offset, Py_NewRef(offset));
2747+
Py_XSETREF(self->text, Py_NewRef(text));
2748+
Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2749+
Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
2750+
Py_XSETREF(self->metadata, Py_XNewRef(metadata));
27492751
Py_DECREF(info);
27502752

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

0 commit comments

Comments
 (0)