Skip to content

Commit 4b35823

Browse files
committed
list: make list_repr thread-safe
This fixes two issues with list_repr: it wasn't thread-safe and it was missing Py_INCREF/DECREF calls for the current element since PyObject_Repr may modify the list. (The second issue also exists upstream)
1 parent f3b6e46 commit 4b35823

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

Objects/listobject.c

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,45 @@ list_dealloc(PyListObject *op)
451451
Py_TRASHCAN_END
452452
}
453453

454+
static int
455+
list_write_repr(PyListObject *v, _PyUnicodeWriter *writer)
456+
{
457+
if (_PyUnicodeWriter_WriteChar(writer, '[') < 0)
458+
return -1;
459+
460+
for (Py_ssize_t i = 0; i < Py_SIZE(v); ++i) {
461+
if (i > 0) {
462+
if (_PyUnicodeWriter_WriteASCIIString(writer, ", ", 2) < 0)
463+
return -1;
464+
}
465+
466+
PyObject *item = v->ob_item[i];
467+
Py_INCREF(item);
468+
PyObject *s = PyObject_Repr(item);
469+
Py_DECREF(item);
470+
if (s == NULL)
471+
return -1;
472+
473+
if (_PyUnicodeWriter_WriteStr(writer, s) < 0) {
474+
Py_DECREF(s);
475+
return -1;
476+
}
477+
Py_DECREF(s);
478+
}
479+
480+
writer->overallocate = 0;
481+
if (_PyUnicodeWriter_WriteChar(writer, ']') < 0)
482+
return -1;
483+
484+
return 0;
485+
}
486+
454487
static PyObject *
455488
list_repr(PyListObject *v)
456489
{
457490
Py_ssize_t i;
458-
PyObject *s;
459491
_PyUnicodeWriter writer;
492+
int err;
460493

461494
if (Py_SIZE(v) == 0) {
462495
return PyUnicode_FromString("[]");
@@ -472,30 +505,13 @@ list_repr(PyListObject *v)
472505
/* "[" + "1" + ", 2" * (len - 1) + "]" */
473506
writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1;
474507

475-
if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0)
476-
goto error;
477-
478508
/* Do repr() on each element. Note that this may mutate the list,
479509
so must refetch the list size on each iteration. */
480-
for (i = 0; i < Py_SIZE(v); ++i) {
481-
if (i > 0) {
482-
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
483-
goto error;
484-
}
485-
486-
s = PyObject_Repr(v->ob_item[i]);
487-
if (s == NULL)
488-
goto error;
489-
490-
if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) {
491-
Py_DECREF(s);
492-
goto error;
493-
}
494-
Py_DECREF(s);
495-
}
510+
Py_BEGIN_CRITICAL_SECTION(&v->mutex);
511+
err = list_write_repr(v, &writer);
512+
Py_END_CRITICAL_SECTION;
496513

497-
writer.overallocate = 0;
498-
if (_PyUnicodeWriter_WriteChar(&writer, ']') < 0)
514+
if (err)
499515
goto error;
500516

501517
Py_ReprLeave((PyObject *)v);

0 commit comments

Comments
 (0)