Skip to content

Commit bf69fc5

Browse files
committed
Improve thread safety of _PyList_AsTupleTakeItems
1 parent f4c0a29 commit bf69fc5

File tree

3 files changed

+12
-10
lines changed

3 files changed

+12
-10
lines changed

Objects/abstract.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,9 +2038,6 @@ PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
20382038
PyObject *
20392039
PySequence_Tuple(PyObject *v)
20402040
{
2041-
PyObject *it; /* iter(v) */
2042-
Py_ssize_t n; /* guess for result tuple size */
2043-
20442041
if (v == NULL) {
20452042
return null_error();
20462043
}
@@ -2057,7 +2054,7 @@ PySequence_Tuple(PyObject *v)
20572054
return PyList_AsTuple(v);
20582055

20592056
/* Get iterator. */
2060-
it = PyObject_GetIter(v);
2057+
PyObject *it = PyObject_GetIter(v);
20612058
if (it == NULL)
20622059
return NULL;
20632060

Objects/listobject.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,20 +3177,24 @@ PyList_AsTuple(PyObject *v)
31773177
PyObject *
31783178
_PyList_AsTupleTakeItems(PyObject *v)
31793179
{
3180-
if (v == NULL || !PyList_Check(v)) {
3181-
PyErr_BadInternalCall();
3182-
return NULL;
3183-
}
3180+
assert(PyList_Check(v));
31843181
PyObject *ret;
31853182
PyListObject *self = (PyListObject *)v;
31863183
if (Py_SIZE(v) == 0) {
31873184
return PyTuple_New(0);
31883185
}
3186+
Py_ssize_t size;
3187+
PyObject **items;
31893188
Py_BEGIN_CRITICAL_SECTION(self);
3190-
Py_ssize_t size = Py_SIZE(v);
3189+
size = Py_SIZE(v);
3190+
items = self->ob_item;
31913191
Py_SET_SIZE(v, 0);
3192-
ret = _PyTuple_FromArraySteal(self->ob_item, size);
3192+
self->ob_item = NULL;
31933193
Py_END_CRITICAL_SECTION();
3194+
ret = _PyTuple_FromArraySteal(items, size);
3195+
if (size) {
3196+
free_list_items(items, false);
3197+
}
31943198
return ret;
31953199
}
31963200

Objects/tupleobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ PyTuple_GetItem(PyObject *op, Py_ssize_t i)
105105
int
106106
PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem)
107107
{
108+
assert(newitem != NULL);
108109
PyObject **p;
109110
if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) {
110111
Py_XDECREF(newitem);

0 commit comments

Comments
 (0)