10000 gh-112087: Make list_{count, index, contains} to be thread-safe. (gh-… · python/cpython@f7a22a7 · GitHub
[go: up one dir, main page]

Skip to content

Commit f7a22a7

Browse files
authored
gh-112087: Make list_{count, index, contains} to be thread-safe. (gh-114916)
1 parent de61d4b commit f7a22a7

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

Objects/listobject.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ PyList_GetItemRef(PyObject *op, Py_ssize_t i)
272272
return Py_NewRef(PyList_GET_ITEM(op, i));
273273
}
274274

275+
static inline PyObject*
276+
list_get_item_ref(PyListObject *op, Py_ssize_t i)
277+
{
278+
if (!valid_index(i, Py_SIZE(op))) {
279+
return NULL;
280+
}
281+
return Py_NewRef(PyList_GET_ITEM(op, i));
282+
}
283+
275284
int
276285
PyList_SetItem(PyObject *op, Py_ssize_t i,
277286
PyObject *newitem)
@@ -478,18 +487,20 @@ list_length(PyObject *a)
478487
static int
479488
list_contains(PyObject *aa, PyObject *el)
480489
{
481-
PyListObject *a = (PyListObject *)aa;
482-
PyObject *item;
483-
Py_ssize_t i;
484-
int cmp;
485490

486-
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) {
487-
item = PyList_GET_ITEM(a, i);
488-
Py_INCREF(item);
489-
cmp = PyObject_RichCompareBool(item, el, Py_EQ);
491+
for (Py_ssize_t i = 0; ; i++) {
492+
PyObject *item = list_get_item_ref((PyListObject *)aa, i);
493+
if (item == NULL) {
494+
// out-of-bounds
495+
return 0;
496+
}
497+
int cmp = PyObject_RichCompareBool(item, el, Py_EQ);
490498
Py_DECREF(item);
499+
if (cmp != 0) {
500+
return cmp;
501+
}
491502
}
492-
return cmp;
503+
return 0;
493504
}
494505

495506
static PyObject *
@@ -2724,8 +2735,6 @@ list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
27242735
Py_ssize_t stop)
27252736
/*[clinic end generated code: output=ec51b88787e4e481 input=40ec5826303a0eb1]*/
27262737
{
2727-
Py_ssize_t i;
2728-
27292738
if (start < 0) {
27302739
start += Py_SIZE(self);
27312740
if (start < 0)
@@ -2736,9 +2745,12 @@ list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
27362745
if (stop < 0)
27372746
stop = 0;
27382747
}
2739-
for (i = start; i < stop && i < Py_SIZE(self); i++) {
2740-
PyObject *obj = self->ob_item[i];
2741-
Py_INCREF(obj);
2748+
for (Py_ssize_t i = start; i < stop; i++) {
2749+
PyObject *obj = list_get_item_ref(self, i);
2750+
if (obj == NULL) {
2751+
// out-of-bounds
2752+
break;
2753+
}
27422754
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
27432755
Py_DECREF(obj);
27442756
if (cmp > 0)
@@ -2764,15 +2776,17 @@ list_count(PyListObject *self, PyObject *value)
27642776
/*[clinic end generated code: output=b1f5d284205ae714 input=3bdc3a5e6f749565]*/
27652777
{
27662778
Py_ssize_t count = 0;
2767-
Py_ssize_t i;
2768-
2769-
for (i = 0; i < Py_SIZE(self); i++) {
2770-
PyObject *obj = self->ob_item[i];
2779+
for (Py_ssize_t i = 0; ; i++) {
2780+
PyObject *obj = list_get_item_ref(self, i);
2781+
if (obj == NULL) {
2782+
// out-of-bounds
2783+
break;
2784+
}
27712785
if (obj == value) {
27722786
count++;
2787+
Py_DECREF(obj);
27732788
continue;
27742789
}
2775-
Py_INCREF(obj);
27762790
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
27772791
Py_DECREF(obj);
27782792
if (cmp > 0)

0 commit comments

Comments
 (0)
0