https://github.com/python/cpython/commit/3de0f55f3410ae835923d10ae098558900a9a121
commit: 3de0f55f3410ae835923d10ae098558900a9a121
branch: 3.13
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2025-04-23T15:44:33+02:00
summary:
[3.13] gh-132713: Fix repr(list) race condition (#132801) (#132809)
Hold a strong reference to the item while calling repr(item).
(cherry picked from commit a4ea80d52394bafffb2257abbe815c7ffdb003a3)
files:
A Misc/NEWS.d/next/Core and
Builtins/2025-04-22-16-38-43.gh-issue-132713.mBWTSZ.rst
M Lib/test/test_list.py
M Objects/listobject.c
diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py
index 005374f429399f..23ef902aa0be34 100644
--- a/Lib/test/test_list.py
+++ b/Lib/test/test_list.py
@@ -116,6 +116,19 @@ def test_list_resize_overflow(self):
with self.assertRaises((MemoryError, OverflowError)):
lst *= size
+ def test_repr_mutate(self):
+ class Obj:
+ @staticmethod
+ def __repr__():
+ try:
+ mylist.pop()
+ except IndexError:
+ pass
+ return 'obj'
+
+ mylist = [Obj() for _ in range(5)]
+ self.assertEqual(repr(mylist), '[obj, obj, obj]')
+
def test_repr_large(self):
# Check the repr of large list objects
def check(n):
diff --git a/Misc/NEWS.d/next/Core and
Builtins/2025-04-22-16-38-43.gh-issue-132713.mBWTSZ.rst b/Misc/NEWS.d/next/Core
and Builtins/2025-04-22-16-38-43.gh-issue-132713.mBWTSZ.rst
new file mode 100644
index 00000000000000..877b42374a396e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and
Builtins/2025-04-22-16-38-43.gh-issue-132713.mBWTSZ.rst
@@ -0,0 +1,2 @@
+Fix ``repr(list)`` race condition: hold a strong reference to the item while
+calling ``repr(item)``. Patch by Victor Stinner.
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 65a8b06d978df4..04a31f1f34a4bb 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -585,6 +585,7 @@ list_repr_impl(PyListObject *v)
{
PyObject *s;
_PyUnicodeWriter writer;
+ PyObject *item = NULL;
Py_ssize_t i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
return i > 0 ? PyUnicode_FromString("[...]") : NULL;
@@ -601,12 +602,15 @@ list_repr_impl(PyListObject *v)
/* Do repr() on each element. Note that this may mutate the list,
so must refetch the list size on each iteration. */
for (i = 0; i < Py_SIZE(v); ++i) {
+ /* Hold a strong reference since repr(item) can mutate the list */
+ item = Py_NewRef(v->ob_item[i]);
+
if (i > 0) {
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
goto error;
}
- s = PyObject_Repr(v->ob_item[i]);
+ s = PyObject_Repr(item);
if (s == NULL)
goto error;
@@ -615,6 +619,7 @@ list_repr_impl(PyListObject *v)
goto error;
}
Py_DECREF(s);
+ Py_CLEAR(item);
}
writer.overallocate = 0;
@@ -625,6 +630,7 @@ list_repr_impl(PyListObject *v)
return _PyUnicodeWriter_Finish(&writer);
error:
+ Py_XDECREF(item);
_PyUnicodeWriter_Dealloc(&writer);
Py_ReprLeave((PyObject *)v);
return NULL;
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]