Skip to content

Commit a19302d

Browse files
committed
fix UBSan failures for dequeiterobject
1 parent 22e4df8 commit a19302d

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

Modules/_collectionsmodule.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,8 @@ typedef struct {
18981898
Py_ssize_t counter; /* number of items remaining for iteration */
18991899
} dequeiterobject;
19001900

1901+
#define _dequeiterobject_CAST(op) ((dequeiterobject *)(op))
1902+
19011903
static PyObject *
19021904
deque_iter(PyObject *self)
19031905
{
@@ -1920,22 +1922,24 @@ deque_iter(PyObject *self)
19201922
}
19211923

19221924
static int
1923-
dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1925+
dequeiter_traverse(PyObject *op, visitproc visit, void *arg)
19241926
{
1927+
dequeiterobject *dio = _dequeiterobject_CAST(op);
19251928
Py_VISIT(Py_TYPE(dio));
19261929
Py_VISIT(dio->deque);
19271930
return 0;
19281931
}
19291932

19301933
static int
1931-
dequeiter_clear(dequeiterobject *dio)
1934+
dequeiter_clear(PyObject *op)
19321935
{
1936+
dequeiterobject *dio = _dequeiterobject_CAST(op);
19331937
Py_CLEAR(dio->deque);
19341938
return 0;
19351939
}
19361940

19371941
static void
1938-
dequeiter_dealloc(dequeiterobject *dio)
1942+
dequeiter_dealloc(PyObject *dio)
19391943
{
19401944
/* bpo-31095: UnTrack is needed before calling any callbacks */
19411945
PyTypeObject *tp = Py_TYPE(dio);
@@ -1973,9 +1977,10 @@ dequeiter_next_lock_held(dequeiterobject *it, dequeobject *deque)
19731977
}
19741978

19751979
static PyObject *
1976-
dequeiter_next(dequeiterobject *it)
1980+
dequeiter_next(PyObject *op)
19771981
{
19781982
PyObject *result;
1983+
dequeiterobject *it = _dequeiterobject_CAST(op);
19791984
// It's safe to access it->deque without holding the per-object lock for it
19801985
// here; it->deque is only assigned during construction of it.
19811986
dequeobject *deque = it->deque;
@@ -1997,12 +2002,12 @@ dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19972002
return NULL;
19982003
assert(type == state->dequeiter_type);
19992004

2000-
it = (dequeiterobject*)deque_iter((dequeobject *)deque);
2005+
it = (dequeiterobject*)deque_iter(deque);
20012006
if (!it)
20022007
return NULL;
20032008
/* consume items from the queue */
20042009
for(i=0; i<index; i++) {
2005-
PyObject *item = dequeiter_next(it);
2010+
PyObject *item = dequeiter_next((PyObject *)it);
20062011
if (item) {
20072012
Py_DECREF(item);
20082013
} else {
@@ -2022,32 +2027,34 @@ dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20222027
}
20232028

20242029
static PyObject *
2025-
dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
2030+
dequeiter_len(PyObject *op, PyObject *Py_UNUSED(args))
20262031
{
2032+
dequeiterobject *it = _dequeiterobject_CAST(op);
20272033
Py_ssize_t len = FT_ATOMIC_LOAD_SSIZE(it->counter);
20282034
return PyLong_FromSsize_t(len);
20292035
}
20302036

20312037
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
20322038

20332039
static PyObject *
2034-
dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
2040+
dequeiter_reduce(PyObject *op, PyObject *Py_UNUSED(args))
20352041
{
2042+
dequeiterobject *it = _dequeiterobject_CAST(op);
20362043
PyTypeObject *ty = Py_TYPE(it);
20372044
// It's safe to access it->deque without holding the per-object lock for it
20382045
// here; it->deque is only assigned during construction of it.
20392046
dequeobject *deque = it->deque;
20402047
Py_ssize_t size, counter;
20412048
Py_BEGIN_CRITICAL_SECTION2(it, deque);
2042-
size = Py_SIZE(deque);
2049+
size = Py_SIZE((PyObject *)deque);
20432050
counter = it->counter;
20442051
Py_END_CRITICAL_SECTION2();
20452052
return Py_BuildValue("O(On)", ty, deque, size - counter);
20462053
}
20472054

20482055
static PyMethodDef dequeiter_methods[] = {
2049-
{"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
2050-
{"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
2056+
{"__length_hint__", dequeiter_len, METH_NOARGS, length_hint_doc},
2057+
{"__reduce__", dequeiter_reduce, METH_NOARGS, reduce_doc},
20512058
{NULL, NULL} /* sentinel */
20522059
};
20532060

@@ -2121,9 +2128,10 @@ dequereviter_next_lock_held(dequeiterobject *it, dequeobject *deque)
21212128
}
21222129

21232130
static PyObject *
2124-
dequereviter_next(dequeiterobject *it)
2131+
dequereviter_next(PyObject *self)
21252132
{
21262133
PyObject *item;
2134+
dequeiterobject *it = _dequeiterobject_CAST(self);
21272135
// It's safe to access it->deque without holding the per-object lock for it
21282136
// here; it->deque is only assigned during construction of it.
21292137
dequeobject *deque = it->deque;
@@ -2149,7 +2157,7 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
21492157
return NULL;
21502158
/* consume items from the queue */
21512159
for(i=0; i<index; i++) {
2152-
PyObject *item = dequereviter_next(it);
2160+
PyObject *item = dequereviter_next((PyObject *)it);
21532161
if (item) {
21542162
Py_DECREF(item);
21552163
} else {

0 commit comments

Comments
 (0)