Skip to content

Commit c09ccd9

Browse files
aiskbrijkapadia
andauthored
[3.13] gh-146250: Fix memory leak in re-initialization of SyntaxError (GH-146251) (#146519)
* [3.13] gh-146250: Fix memory leak in re-initialization of `SyntaxError` (GH-146251) (cherry picked from commit 0de4e08) Co-authored-by: Brij Kapadia <97006829+bkap123@users.noreply.github.com> * Minimize the changes * Minimize the changes * Minimize the changes --------- Co-authored-by: Brij Kapadia <97006829+bkap123@users.noreply.github.com>
1 parent 0dcb625 commit c09ccd9

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

Lib/test/test_exceptions.py

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

2439+
def test_syntax_error_memory_leak(self):
2440+
# gh-146250: memory leak with re-initialization of SyntaxError
2441+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2442+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4))
2443+
self.assertEqual(e.msg, "new_msg")
2444+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4)))
2445+
self.assertEqual(e.filename, "new_file.py")
2446+
self.assertEqual(e.lineno, 2)
2447+
self.assertEqual(e.offset, 3)
2448+
self.assertEqual(e.text, "new_txt")
2449+
self.assertEqual(e.end_lineno, 3)
2450+
self.assertEqual(e.end_offset, 4)
2451+
2452+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2453+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt"))
2454+
self.assertEqual(e.msg, "new_msg")
2455+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt")))
2456+
self.assertEqual(e.filename, "new_file.py")
2457+
self.assertEqual(e.lineno, 2)
2458+
self.assertEqual(e.offset, 3)
2459+
self.assertEqual(e.text, "new_txt")
2460+
self.assertIsNone(e.end_lineno)
2461+
self.assertIsNone(e.end_offset)
2462+
24392463

24402464
class TestInvalidExceptionMatcher(unittest.TestCase):
24412465
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: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,22 +2466,23 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
24662466
return -1;
24672467
}
24682468

2469-
self->end_lineno = NULL;
2470-
self->end_offset = NULL;
2469+
PyObject *filename, *lineno, *offset, *text;
2470+
PyObject *end_lineno = NULL;
2471+
PyObject *end_offset = NULL;
24712472
if (!PyArg_ParseTuple(info, "OOOO|OO",
2472-
&self->filename, &self->lineno,
2473-
&self->offset, &self->text,
2474-
&self->end_lineno, &self->end_offset)) {
2473+
&filename, &lineno,
2474+
&offset, &text,
2475+
&end_lineno, &end_offset)) {
24752476
Py_DECREF(info);
24762477
return -1;
24772478
}
24782479

2479-
Py_INCREF(self->filename);
2480-
Py_INCREF(self->lineno);
2481-
Py_INCREF(self->offset);
2482-
Py_INCREF(self->text);
2483-
Py_XINCREF(self->end_lineno);
2484-
Py_XINCREF(self->end_offset);
2480+
Py_XSETREF(self->filename, Py_NewRef(filename));
2481+
Py_XSETREF(self->lineno, Py_NewRef(lineno));
2482+
Py_XSETREF(self->offset, Py_NewRef(offset));
2483+
Py_XSETREF(self->text, Py_NewRef(text));
2484+
Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2485+
Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
24852486
Py_DECREF(info);
24862487

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

0 commit comments

Comments
 (0)