From ef9f7620fe8dcce87d9b1ca99bb7a0e220e49adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:05:44 +0100 Subject: [PATCH 01/23] fix UBSan failures for `batchedobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 3f736f0cf19968..1ab8025ca40f01 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -104,6 +104,8 @@ typedef struct { bool strict; } batchedobject; +#define batchedobject_CAST(op) ((batchedobject *)(op)) + /*[clinic input] @classmethod itertools.batched.__new__ as batched_new @@ -165,8 +167,9 @@ batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n, } static void -batched_dealloc(batchedobject *bo) +batched_dealloc(PyObject *op) { + batchedobject *bo = batchedobject_CAST(op); PyTypeObject *tp = Py_TYPE(bo); PyObject_GC_UnTrack(bo); Py_XDECREF(bo->it); @@ -175,16 +178,18 @@ batched_dealloc(batchedobject *bo) } static int -batched_traverse(batchedobject *bo, visitproc visit, void *arg) +batched_traverse(PyObject *op, visitproc visit, void *arg) { + batchedobject *bo = batchedobject_CAST(op); Py_VISIT(Py_TYPE(bo)); Py_VISIT(bo->it); return 0; } static PyObject * -batched_next(batchedobject *bo) +batched_next(PyObject *op) { + batchedobject *bo = batchedobject_CAST(op); Py_ssize_t i; Py_ssize_t n = bo->batch_size; PyObject *it = bo->it; From 8cfd9f39872ba62e2bda15b454a0942644204fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:07:23 +0100 Subject: [PATCH 02/23] fix UBSan failures for `pairwiseobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1ab8025ca40f01..c3ec05692997c9 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -270,6 +270,8 @@ typedef struct { PyObject *result; } pairwiseobject; +#define pairwiseobject_CAST(op) ((pairwiseobject *)(op)) + /*[clinic input] @classmethod itertools.pairwise.__new__ as pairwise_new @@ -308,8 +310,9 @@ pairwise_new_impl(PyTypeObject *type, PyObject *iterable) } static void -pairwise_dealloc(pairwiseobject *po) +pairwise_dealloc(PyObject *op) { + pairwiseobject *po = pairwiseobject_CAST(op); PyTypeObject *tp = Py_TYPE(po); PyObject_GC_UnTrack(po); Py_XDECREF(po->it); @@ -320,8 +323,9 @@ pairwise_dealloc(pairwiseobject *po) } static int -pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) +pairwise_traverse(PyObject *op, visitproc visit, void *arg) { + pairwiseobject *po = pairwiseobject_CAST(op); Py_VISIT(Py_TYPE(po)); Py_VISIT(po->it); Py_VISIT(po->old); @@ -330,8 +334,9 @@ pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) } static PyObject * -pairwise_next(pairwiseobject *po) +pairwise_next(PyObject *op) { + pairwiseobject *po = pairwiseobject_CAST(op); PyObject *it = po->it; PyObject *old = po->old; PyObject *new, *result; From a50c28f069a4b068ff967d84bd636099babe7f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:08:32 +0100 Subject: [PATCH 03/23] fix UBSan failures for `groupbyobject` --- Modules/itertoolsmodule.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index c3ec05692997c9..300c1dc20dd54d 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -429,6 +429,8 @@ typedef struct { itertools_state *state; } groupbyobject; +#define groupbyobject_CAST(op) ((groupbyobject *)(op)) + static PyObject *_grouper_create(groupbyobject *, PyObject *); /*[clinic input] @@ -468,8 +470,9 @@ itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc) } static void -groupby_dealloc(groupbyobject *gbo) +groupby_dealloc(PyObject *op) { + groupbyobject *gbo = groupbyobject_CAST(op); PyTypeObject *tp = Py_TYPE(gbo); PyObject_GC_UnTrack(gbo); Py_XDECREF(gbo->it); @@ -482,8 +485,9 @@ groupby_dealloc(groupbyobject *gbo) } static int -groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) +groupby_traverse(PyObject *op, visitproc visit, void *arg) { + groupbyobject *gbo = groupbyobject_CAST(op); Py_VISIT(Py_TYPE(gbo)); Py_VISIT(gbo->it); Py_VISIT(gbo->keyfunc); @@ -520,9 +524,10 @@ groupby_step(groupbyobject *gbo) } static PyObject * -groupby_next(groupbyobject *gbo) +groupby_next(PyObject *op) { PyObject *r, *grouper; + groupbyobject *gbo = groupbyobject_CAST(op); gbo->currgrouper = NULL; /* skip to next iteration group */ @@ -598,7 +603,7 @@ itertools__grouper_impl(PyTypeObject *type, PyObject *parent, PyObject *tgtkey) /*[clinic end generated code: output=462efb1cdebb5914 input=afe05eb477118f12]*/ { - return _grouper_create((groupbyobject*) parent, tgtkey); + return _grouper_create(groupbyobject_CAST(parent), tgtkey); } static PyObject * @@ -639,7 +644,7 @@ _grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) static PyObject * _grouper_next(_grouperobject *igo) { - groupbyobject *gbo = (groupbyobject *)igo->parent; + groupbyobject *gbo = groupbyobject_CAST(igo->parent); PyObject *r; int rcmp; From c61c1daaee75e19c16c81bc3f912f2406015af1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:11:05 +0100 Subject: [PATCH 04/23] fix UBSan failures for `_grouperobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 300c1dc20dd54d..1238436eb5610f 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -589,6 +589,8 @@ typedef struct { PyObject *tgtkey; } _grouperobject; +#define _grouperobject_CAST(op) ((_grouperobject *)(op)) + /*[clinic input] @classmethod itertools._grouper.__new__ @@ -622,8 +624,9 @@ _grouper_create(groupbyobject *parent, PyObject *tgtkey) } static void -_grouper_dealloc(_grouperobject *igo) +_grouper_dealloc(PyObject *op) { + _grouperobject *igo = _grouperobject_CAST(op); PyTypeObject *tp = Py_TYPE(igo); PyObject_GC_UnTrack(igo); Py_DECREF(igo->parent); @@ -633,8 +636,9 @@ _grouper_dealloc(_grouperobject *igo) } static int -_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) +_grouper_traverse(PyObject *op, visitproc visit, void *arg) { + _grouperobject *igo = _grouperobject_CAST(op); Py_VISIT(Py_TYPE(igo)); Py_VISIT(igo->parent); Py_VISIT(igo->tgtkey); @@ -642,8 +646,9 @@ _grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) } static PyObject * -_grouper_next(_grouperobject *igo) +_grouper_next(PyObject *op) { + _grouperobject *igo = _grouperobject_CAST(op); groupbyobject *gbo = groupbyobject_CAST(igo->parent); PyObject *r; int rcmp; From 7a02ffcb4c518e2df967fac0911870a5dc4163e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:15:35 +0100 Subject: [PATCH 05/23] fix UBSan failures for `teedataobject` --- Modules/itertoolsmodule.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1238436eb5610f..e82dd28d6fc014 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -714,6 +714,8 @@ typedef struct { PyObject *(values[LINKCELLS]); } teedataobject; +#define teedataobject_CAST(op) ((teedataobject *)(op)) + typedef struct { PyObject_HEAD teedataobject *dataobj; @@ -775,9 +777,10 @@ teedataobject_getitem(teedataobject *tdo, int i) } static int -teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) +teedataobject_traverse(PyObject *op, visitproc visit, void * arg) { int i; + teedataobject *tdo = teedataobject_CAST(op); Py_VISIT(Py_TYPE(tdo)); Py_VISIT(tdo->it); @@ -791,18 +794,20 @@ static void teedataobject_safe_decref(PyObject *obj) { while (obj && Py_REFCNT(obj) == 1) { - PyObject *nextlink = ((teedataobject *)obj)->nextlink; - ((teedataobject *)obj)->nextlink = NULL; + teedataobject *tmp = teedataobject_CAST(obj); + PyObject *nextlink = tmp->nextlink; + tmp->nextlink = NULL; Py_SETREF(obj, nextlink); } Py_XDECREF(obj); } static int -teedataobject_clear(teedataobject *tdo) +teedataobject_clear(PyObject *op) { int i; PyObject *tmp; + teedataobject *tdo = teedataobject_CAST(op); Py_CLEAR(tdo->it); for (i=0 ; inumread ; i++) @@ -814,12 +819,12 @@ teedataobject_clear(teedataobject *tdo) } static void -teedataobject_dealloc(teedataobject *tdo) +teedataobject_dealloc(PyObject *op) { - PyTypeObject *tp = Py_TYPE(tdo); - PyObject_GC_UnTrack(tdo); - teedataobject_clear(tdo); - PyObject_GC_Del(tdo); + PyTypeObject *tp = Py_TYPE(op); + PyObject_GC_UnTrack(op); + (void)teedataobject_clear(op); + PyObject_GC_Del(op); Py_DECREF(tp); } From b0f971a621e2ebd153c393c5aaaf2b63883ba9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:21:06 +0100 Subject: [PATCH 06/23] fix UBSan failures for `teeobject` --- Modules/itertoolsmodule.c | 53 +++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index e82dd28d6fc014..bc12547860bcdc 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -724,6 +724,8 @@ typedef struct { itertools_state *state; } teeobject; +#define teeobject_CAST(op) ((teeobject *)(op)) + static PyObject * teedataobject_newinternal(itertools_state *state, PyObject *it) { @@ -903,8 +905,9 @@ static PyType_Spec teedataobject_spec = { static PyObject * -tee_next(teeobject *to) +tee_next(PyObject *op) { + teeobject *to = teeobject_CAST(op); PyObject *value, *link; if (to->index >= LINKCELLS) { @@ -922,27 +925,34 @@ tee_next(teeobject *to) } static int -tee_traverse(teeobject *to, visitproc visit, void *arg) +tee_traverse(PyObject *op, visitproc visit, void *arg) { + teeobject *to = teeobject_CAST(op); Py_VISIT(Py_TYPE(to)); - Py_VISIT((PyObject *)to->dataobj); + Py_VISIT(to->dataobj); return 0; } -static PyObject * -tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) +static teeobject * +tee_copy_impl(teeobject *to) { - teeobject *newto; - - newto = PyObject_GC_New(teeobject, Py_TYPE(to)); - if (newto == NULL) + teeobject *newto = PyObject_GC_New(teeobject, Py_TYPE(to)); + if (newto == NULL) { return NULL; - newto->dataobj = (teedataobject*)Py_NewRef(to->dataobj); + } + newto->dataobj = (teedataobject *)Py_NewRef(to->dataobj); newto->index = to->index; newto->weakreflist = NULL; newto->state = to->state; PyObject_GC_Track(newto); - return (PyObject *)newto; + return newto; +} + +static inline PyObject * +tee_copy(PyObject *op, PyObject *Py_UNUSED(ignored)) +{ + teeobject *to = teeobject_CAST(op); + return (PyObject *)tee_copy_impl(to); } PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator."); @@ -957,7 +967,7 @@ tee_fromiterable(itertools_state *state, PyObject *iterable) if (it == NULL) return NULL; if (PyObject_TypeCheck(it, state->tee_type)) { - to = (teeobject *)tee_copy((teeobject *)it, NULL); + to = tee_copy_impl((teeobject *)it); // 'it' can be fast casted goto done; } @@ -998,26 +1008,27 @@ itertools__tee_impl(PyTypeObject *type, PyObject *iterable) } static int -tee_clear(teeobject *to) +tee_clear(PyObject *op) { + teeobject *to = teeobject_CAST(op); if (to->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) to); + PyObject_ClearWeakRefs(op); Py_CLEAR(to->dataobj); return 0; } static void -tee_dealloc(teeobject *to) +tee_dealloc(PyObject *op) { - PyTypeObject *tp = Py_TYPE(to); - PyObject_GC_UnTrack(to); - tee_clear(to); - PyObject_GC_Del(to); + PyTypeObject *tp = Py_TYPE(op); + PyObject_GC_UnTrack(op); + (void)tee_clear(op); + PyObject_GC_Del(op); Py_DECREF(tp); } static PyMethodDef tee_methods[] = { - {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, + {"__copy__", tee_copy, METH_NOARGS, teecopy_doc}, {NULL, NULL} /* sentinel */ }; @@ -1088,7 +1099,7 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) PyTuple_SET_ITEM(result, 0, to); for (i = 1; i < n; i++) { - to = tee_copy((teeobject *)to, NULL); + to = tee_copy(to, NULL); if (to == NULL) { Py_DECREF(result); return NULL; From 8dc8779992a62116109b54a85ce835bbbb3aa706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:22:57 +0100 Subject: [PATCH 07/23] fix UBSan failures for `cycleobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index bc12547860bcdc..1ca9c3ceaf1034 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1120,6 +1120,8 @@ typedef struct { int firstpass; } cycleobject; +#define cycleobject_CAST(op) ((cycleobject *)(op)) + /*[clinic input] @classmethod itertools.cycle.__new__ @@ -1163,8 +1165,9 @@ itertools_cycle_impl(PyTypeObject *type, PyObject *iterable) } static void -cycle_dealloc(cycleobject *lz) +cycle_dealloc(PyObject *op) { + cycleobject *lz = cycleobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); @@ -1174,8 +1177,9 @@ cycle_dealloc(cycleobject *lz) } static int -cycle_traverse(cycleobject *lz, visitproc visit, void *arg) +cycle_traverse(PyObject *op, visitproc visit, void *arg) { + cycleobject *lz = cycleobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->saved); @@ -1183,8 +1187,9 @@ cycle_traverse(cycleobject *lz, visitproc visit, void *arg) } static PyObject * -cycle_next(cycleobject *lz) +cycle_next(PyObject *op) { + cycleobject *lz = cycleobject_CAST(op); PyObject *item; if (lz->it != NULL) { From 27e83cf2b0d4432121c2186cc419f1d51ae2b213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:26:20 +0100 Subject: [PATCH 08/23] fix UBSan failures for `dropwhileobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1ca9c3ceaf1034..388941a9afbdc9 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1247,6 +1247,8 @@ typedef struct { long start; } dropwhileobject; +#define dropwhileobject_CAST(op) ((dropwhileobject *)(op)) + /*[clinic input] @classmethod itertools.dropwhile.__new__ @@ -1284,8 +1286,9 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) } static void -dropwhile_dealloc(dropwhileobject *lz) +dropwhile_dealloc(PyObject *op) { + dropwhileobject *lz = dropwhileobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); @@ -1295,8 +1298,9 @@ dropwhile_dealloc(dropwhileobject *lz) } static int -dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) +dropwhile_traverse(PyObject *op, visitproc visit, void *arg) { + dropwhileobject *lz = dropwhileobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); @@ -1304,8 +1308,9 @@ dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) } static PyObject * -dropwhile_next(dropwhileobject *lz) +dropwhile_next(PyObject *op) { + dropwhileobject *lz = dropwhileobject_CAST(op); PyObject *item, *good; PyObject *it = lz->it; long ok; From 517b00ea8309e610cf0a3e97bf0461fd07a01135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:27:15 +0100 Subject: [PATCH 09/23] fix UBSan failures for `takewhileobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 388941a9afbdc9..e70cb426828d14 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1371,6 +1371,8 @@ typedef struct { long stop; } takewhileobject; +#define takewhileobject_CAST(op) ((takewhileobject *)(op)) + /*[clinic input] @classmethod itertools.takewhile.__new__ @@ -1406,8 +1408,9 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) } static void -takewhile_dealloc(takewhileobject *lz) +takewhile_dealloc(PyObject *op) { + takewhileobject *lz = takewhileobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); @@ -1417,8 +1420,9 @@ takewhile_dealloc(takewhileobject *lz) } static int -takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) +takewhile_traverse(PyObject *op, visitproc visit, void *arg) { + takewhileobject *lz = takewhileobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); @@ -1426,8 +1430,9 @@ takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) } static PyObject * -takewhile_next(takewhileobject *lz) +takewhile_next(PyObject *op) { + takewhileobject *lz = takewhileobject_CAST(op); PyObject *item, *good; PyObject *it = lz->it; long ok; From 5b3b086f48a20e63556e754827ff4a20fae9fee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:28:19 +0100 Subject: [PATCH 10/23] fix UBSan failures for `isliceobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index e70cb426828d14..92252f8fdbe5e2 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1491,6 +1491,8 @@ typedef struct { Py_ssize_t cnt; } isliceobject; +#define isliceobject_CAST(op) ((isliceobject *)(op)) + static PyObject * islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1579,8 +1581,9 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static void -islice_dealloc(isliceobject *lz) +islice_dealloc(PyObject *op) { + isliceobject *lz = isliceobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); @@ -1589,16 +1592,18 @@ islice_dealloc(isliceobject *lz) } static int -islice_traverse(isliceobject *lz, visitproc visit, void *arg) +islice_traverse(PyObject *op, visitproc visit, void *arg) { + isliceobject *lz = isliceobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); return 0; } static PyObject * -islice_next(isliceobject *lz) +islice_next(PyObject *op) { + isliceobject *lz = isliceobject_CAST(op); PyObject *item; PyObject *it = lz->it; Py_ssize_t stop = lz->stop; From b3a53d30eb6f58886674ffd449622aee139a1f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:29:02 +0100 Subject: [PATCH 11/23] fix UBSan failures for `starmapobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 92252f8fdbe5e2..aaf4c66633732d 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1680,6 +1680,8 @@ typedef struct { PyObject *it; } starmapobject; +#define starmapobject_CAST(op) ((starmapobject *)(op)) + /*[clinic input] @classmethod itertools.starmap.__new__ @@ -1714,8 +1716,9 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) } static void -starmap_dealloc(starmapobject *lz) +starmap_dealloc(PyObject *op) { + starmapobject *lz = starmapobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); @@ -1725,8 +1728,9 @@ starmap_dealloc(starmapobject *lz) } static int -starmap_traverse(starmapobject *lz, visitproc visit, void *arg) +starmap_traverse(PyObject *op, visitproc visit, void *arg) { + starmapobject *lz = starmapobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); @@ -1734,8 +1738,9 @@ starmap_traverse(starmapobject *lz, visitproc visit, void *arg) } static PyObject * -starmap_next(starmapobject *lz) +starmap_next(PyObject *op) { + starmapobject *lz = starmapobject_CAST(op); PyObject *args; PyObject *result; PyObject *it = lz->it; From 02d369500e1fcc4084a1d82d348d8f37210551e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:30:20 +0100 Subject: [PATCH 12/23] fix UBSan failures for `chainobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index aaf4c66633732d..00c14e2ddcb6df 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1789,6 +1789,8 @@ typedef struct { PyObject *active; /* Currently running input iterator */ } chainobject; +#define chainobject_CAST(op) ((chainobject *)(op)) + static PyObject * chain_new_internal(PyTypeObject *type, PyObject *source) { @@ -1845,8 +1847,9 @@ itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg) } static void -chain_dealloc(chainobject *lz) +chain_dealloc(PyObject *op) { + chainobject *lz = chainobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->active); @@ -1856,8 +1859,9 @@ chain_dealloc(chainobject *lz) } static int -chain_traverse(chainobject *lz, visitproc visit, void *arg) +chain_traverse(PyObject *op, visitproc visit, void *arg) { + chainobject *lz = chainobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->source); Py_VISIT(lz->active); @@ -1865,8 +1869,9 @@ chain_traverse(chainobject *lz, visitproc visit, void *arg) } static PyObject * -chain_next(chainobject *lz) +chain_next(PyObject *op) { + chainobject *lz = chainobject_CAST(op); PyObject *item; /* lz->source is the iterator of iterables. If it's NULL, we've already From d45dc28045ae94b1f59a643e21bbd95ea5eb68e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:32:29 +0100 Subject: [PATCH 13/23] fix UBSan failures for `productobject` --- Modules/itertoolsmodule.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 00c14e2ddcb6df..f4a664f863e842 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1954,6 +1954,8 @@ typedef struct { int stopped; /* set to 1 when the iterator is exhausted */ } productobject; +#define productobject_CAST(op) ((productobject *)(op)) + static PyObject * product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2038,21 +2040,22 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static void -product_dealloc(productobject *lz) +product_dealloc(PyObject *op) { + productobject *lz = productobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->pools); Py_XDECREF(lz->result); - if (lz->indices != NULL) - PyMem_Free(lz->indices); + PyMem_Free(lz->indices); tp->tp_free(lz); Py_DECREF(tp); } static PyObject * -product_sizeof(productobject *lz, void *unused) +product_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored)) { + productobject *lz = productobject_CAST(op); size_t res = _PyObject_SIZE(Py_TYPE(lz)); res += (size_t)PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); return PyLong_FromSize_t(res); @@ -2061,8 +2064,9 @@ product_sizeof(productobject *lz, void *unused) PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); static int -product_traverse(productobject *lz, visitproc visit, void *arg) +product_traverse(PyObject *op, visitproc visit, void *arg) { + productobject *lz = productobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->pools); Py_VISIT(lz->result); @@ -2070,8 +2074,9 @@ product_traverse(productobject *lz, visitproc visit, void *arg) } static PyObject * -product_next(productobject *lz) +product_next(PyObject *op) { + productobject *lz = productobject_CAST(op); PyObject *pool; PyObject *elem; PyObject *oldelem; @@ -2156,8 +2161,7 @@ product_next(productobject *lz) } static PyMethodDef product_methods[] = { - {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, - sizeof_doc}, + {"__sizeof__", product_sizeof, METH_NOARGS, sizeof_doc}, {NULL, NULL} /* sentinel */ }; From 36a1b3ce4fd7c61b4fdf8eaa5d83780e7953c044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:34:40 +0100 Subject: [PATCH 14/23] fix UBSan failures for `combinationsobject` --- Modules/itertoolsmodule.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index f4a664f863e842..d70976f5621f14 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2213,6 +2213,7 @@ typedef struct { int stopped; /* set to 1 when the iterator is exhausted */ } combinationsobject; +#define combinationsobject_CAST(op) ((combinationsobject *)(op)) /*[clinic input] @classmethod @@ -2274,29 +2275,31 @@ itertools_combinations_impl(PyTypeObject *type, PyObject *iterable, } static void -combinations_dealloc(combinationsobject *co) +combinations_dealloc(PyObject *op) { + combinationsobject *co = combinationsobject_CAST(op); PyTypeObject *tp = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); - if (co->indices != NULL) - PyMem_Free(co->indices); + PyMem_Free(co->indices); tp->tp_free(co); Py_DECREF(tp); } static PyObject * -combinations_sizeof(combinationsobject *co, void *unused) +combinations_sizeof(PyObject *op, PyObject *Py_UNUSED(args)) { + combinationsobject *co = combinationsobject_CAST(op); size_t res = _PyObject_SIZE(Py_TYPE(co)); res += (size_t)co->r * sizeof(Py_ssize_t); return PyLong_FromSize_t(res); } static int -combinations_traverse(combinationsobject *co, visitproc visit, void *arg) +combinations_traverse(PyObject *op, visitproc visit, void *arg) { + combinationsobject *co = combinationsobject_CAST(op); Py_VISIT(Py_TYPE(co)); Py_VISIT(co->pool); Py_VISIT(co->result); @@ -2304,8 +2307,9 @@ combinations_traverse(combinationsobject *co, visitproc visit, void *arg) } static PyObject * -combinations_next(combinationsobject *co) +combinations_next(PyObject *op) { + combinationsobject *co = combinationsobject_CAST(op); PyObject *elem; PyObject *oldelem; PyObject *pool = co->pool; @@ -2389,8 +2393,7 @@ combinations_next(combinationsobject *co) } static PyMethodDef combinations_methods[] = { - {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, - sizeof_doc}, + {"__sizeof__", combinations_sizeof, METH_NOARGS, sizeof_doc}, {NULL, NULL} /* sentinel */ }; From 56b1dccf4d5886405ba1af415d71cacfd72dd8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:37:29 +0100 Subject: [PATCH 15/23] fix UBSan failures for `cwrobject` --- Modules/itertoolsmodule.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d70976f5621f14..cd034edc844313 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2456,6 +2456,8 @@ typedef struct { int stopped; /* set to 1 when the cwr iterator is exhausted */ } cwrobject; +#define cwrobject_CAST(op) ((cwrobject *)(op)) + /*[clinic input] @classmethod itertools.combinations_with_replacement.__new__ @@ -2517,29 +2519,31 @@ itertools_combinations_with_replacement_impl(PyTypeObject *type, } static void -cwr_dealloc(cwrobject *co) +cwr_dealloc(PyObject *op) { + cwrobject *co = cwrobject_CAST(op); PyTypeObject *tp = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); - if (co->indices != NULL) - PyMem_Free(co->indices); + PyMem_Free(co->indices); tp->tp_free(co); Py_DECREF(tp); } static PyObject * -cwr_sizeof(cwrobject *co, void *unused) +cwr_sizeof(PyObject *op, PyObject *Py_UNUSED(args)) { + cwrobject *co = cwrobject_CAST(op); size_t res = _PyObject_SIZE(Py_TYPE(co)); res += (size_t)co->r * sizeof(Py_ssize_t); return PyLong_FromSize_t(res); } static int -cwr_traverse(cwrobject *co, visitproc visit, void *arg) +cwr_traverse(PyObject *op, visitproc visit, void *arg) { + cwrobject *co = cwrobject_CAST(op); Py_VISIT(Py_TYPE(co)); Py_VISIT(co->pool); Py_VISIT(co->result); @@ -2547,8 +2551,9 @@ cwr_traverse(cwrobject *co, visitproc visit, void *arg) } static PyObject * -cwr_next(cwrobject *co) +cwr_next(PyObject *op) { + cwrobject *co = cwrobject_CAST(op); PyObject *elem; PyObject *oldelem; PyObject *pool = co->pool; @@ -2626,8 +2631,7 @@ cwr_next(cwrobject *co) } static PyMethodDef cwr_methods[] = { - {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, - sizeof_doc}, + {"__sizeof__", cwr_sizeof, METH_NOARGS, sizeof_doc}, {NULL, NULL} /* sentinel */ }; From 8bcb250a0b8d091e27a6bc120e54a53126763aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:40:30 +0100 Subject: [PATCH 16/23] fix UBSan failures for `permutationsobject` --- Modules/itertoolsmodule.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index cd034edc844313..1404b0ae8ba1b5 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2695,6 +2695,8 @@ typedef struct { int stopped; /* set to 1 when the iterator is exhausted */ } permutationsobject; +#define permutationsobject_CAST(op) ((permutationsobject *)(op)) + /*[clinic input] @classmethod itertools.permutations.__new__ @@ -2774,8 +2776,9 @@ itertools_permutations_impl(PyTypeObject *type, PyObject *iterable, } static void -permutations_dealloc(permutationsobject *po) +permutations_dealloc(PyObject *op) { + permutationsobject *po = permutationsobject_CAST(op); PyTypeObject *tp = Py_TYPE(po); PyObject_GC_UnTrack(po); Py_XDECREF(po->pool); @@ -2787,8 +2790,9 @@ permutations_dealloc(permutationsobject *po) } static PyObject * -permutations_sizeof(permutationsobject *po, void *unused) +permutations_sizeof(PyObject *op, PyObject *Py_UNUSED(args)) { + permutationsobject *po = permutationsobject_CAST(op); size_t res = _PyObject_SIZE(Py_TYPE(po)); res += (size_t)PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); res += (size_t)po->r * sizeof(Py_ssize_t); @@ -2796,8 +2800,9 @@ permutations_sizeof(permutationsobject *po, void *unused) } static int -permutations_traverse(permutationsobject *po, visitproc visit, void *arg) +permutations_traverse(PyObject *op, visitproc visit, void *arg) { + permutationsobject *po = permutationsobject_CAST(op); Py_VISIT(Py_TYPE(po)); Py_VISIT(po->pool); Py_VISIT(po->result); @@ -2805,8 +2810,9 @@ permutations_traverse(permutationsobject *po, visitproc visit, void *arg) } static PyObject * -permutations_next(permutationsobject *po) +permutations_next(PyObject *op) { + permutationsobject *po = permutationsobject_CAST(op); PyObject *elem; PyObject *oldelem; PyObject *pool = po->pool; @@ -2895,8 +2901,7 @@ permutations_next(permutationsobject *po) } static PyMethodDef permuations_methods[] = { - {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, - sizeof_doc}, + {"__sizeof__", permutations_sizeof, METH_NOARGS, sizeof_doc}, {NULL, NULL} /* sentinel */ }; From b7723942ad3dc8e13f1099c5492b618e07346eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:41:22 +0100 Subject: [PATCH 17/23] fix UBSan failures for `accumulateobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 1404b0ae8ba1b5..a61362d86a2e2a 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2938,6 +2938,8 @@ typedef struct { itertools_state *state; } accumulateobject; +#define accumulateobject_CAST(op) ((accumulateobject *)(op)) + /*[clinic input] @classmethod itertools.accumulate.__new__ @@ -2979,8 +2981,9 @@ itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, } static void -accumulate_dealloc(accumulateobject *lz) +accumulate_dealloc(PyObject *op) { + accumulateobject *lz = accumulateobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->binop); @@ -2992,8 +2995,9 @@ accumulate_dealloc(accumulateobject *lz) } static int -accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) +accumulate_traverse(PyObject *op, visitproc visit, void *arg) { + accumulateobject *lz = accumulateobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->binop); Py_VISIT(lz->it); @@ -3003,8 +3007,9 @@ accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) } static PyObject * -accumulate_next(accumulateobject *lz) +accumulate_next(PyObject *op) { + accumulateobject *lz = accumulateobject_CAST(op); PyObject *val, *newtotal; if (lz->initial != Py_None) { From b9b3f166bfc9b47f2558980dec5ec0d3fdbb343f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:42:16 +0100 Subject: [PATCH 18/23] fix UBSan failures for `compressobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index a61362d86a2e2a..dc808572db5945 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3075,6 +3075,8 @@ typedef struct { PyObject *selectors; } compressobject; +#define compressobject_CAST(op) ((compressobject *)(op)) + /*[clinic input] @classmethod itertools.compress.__new__ @@ -3115,8 +3117,9 @@ itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2) } static void -compress_dealloc(compressobject *lz) +compress_dealloc(PyObject *op) { + compressobject *lz = compressobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->data); @@ -3126,8 +3129,9 @@ compress_dealloc(compressobject *lz) } static int -compress_traverse(compressobject *lz, visitproc visit, void *arg) +compress_traverse(PyObject *op, visitproc visit, void *arg) { + compressobject *lz = compressobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->data); Py_VISIT(lz->selectors); @@ -3135,8 +3139,9 @@ compress_traverse(compressobject *lz, visitproc visit, void *arg) } static PyObject * -compress_next(compressobject *lz) +compress_next(PyObject *op) { + compressobject *lz = compressobject_CAST(op); PyObject *data = lz->data, *selectors = lz->selectors; PyObject *datum, *selector; PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext; From 658ef78fbd734f521ac0b969f936e4bc59039eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:43:20 +0100 Subject: [PATCH 19/23] fix UBSan failures for `filterfalseobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index dc808572db5945..9c4a5cbd3a5a93 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3204,6 +3204,8 @@ typedef struct { PyObject *it; } filterfalseobject; +#define filterfalseobject_CAST(op) ((filterfalseobject *)(op)) + /*[clinic input] @classmethod itertools.filterfalse.__new__ @@ -3240,8 +3242,9 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) } static void -filterfalse_dealloc(filterfalseobject *lz) +filterfalse_dealloc(PyObject *op) { + filterfalseobject *lz = filterfalseobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); @@ -3251,8 +3254,9 @@ filterfalse_dealloc(filterfalseobject *lz) } static int -filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) +filterfalse_traverse(PyObject *op, visitproc visit, void *arg) { + filterfalseobject *lz = filterfalseobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); @@ -3260,8 +3264,9 @@ filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) } static PyObject * -filterfalse_next(filterfalseobject *lz) +filterfalse_next(PyObject *op) { + filterfalseobject *lz = filterfalseobject_CAST(op); PyObject *item; PyObject *it = lz->it; long ok; From e780c70ba249e9f092a0feb0425c8d84014b1d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:44:29 +0100 Subject: [PATCH 20/23] fix UBSan failures for `countobject` --- Modules/itertoolsmodule.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 9c4a5cbd3a5a93..d50a3369fdcbcc 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3328,6 +3328,8 @@ typedef struct { PyObject *long_step; } countobject; +#define countobject_CAST(op) ((countobject *)(op)) + /* Counting logic and invariants: fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified. @@ -3439,8 +3441,9 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, } static void -count_dealloc(countobject *lz) +count_dealloc(PyObject *op) { + countobject *lz = countobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->long_cnt); @@ -3450,8 +3453,9 @@ count_dealloc(countobject *lz) } static int -count_traverse(countobject *lz, visitproc visit, void *arg) +count_traverse(PyObject *op, visitproc visit, void *arg) { + countobject *lz = countobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->long_cnt); Py_VISIT(lz->long_step); @@ -3481,8 +3485,9 @@ count_nextlong(countobject *lz) } static PyObject * -count_next(countobject *lz) +count_next(PyObject *op) { + countobject *lz = countobject_CAST(op); #ifndef Py_GIL_DISABLED if (lz->cnt == PY_SSIZE_T_MAX) return count_nextlong(lz); @@ -3510,8 +3515,9 @@ count_next(countobject *lz) } static PyObject * -count_repr(countobject *lz) +count_repr(PyObject *op) { + countobject *lz = countobject_CAST(op); if (lz->long_cnt == NULL) return PyUnicode_FromFormat("%s(%zd)", _PyType_Name(Py_TYPE(lz)), lz->cnt); From b37679153f0e5cb1d0fbbea8e3e88beaa775cd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:45:50 +0100 Subject: [PATCH 21/23] fix UBSan failures for `repeatobject` --- Modules/itertoolsmodule.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d50a3369fdcbcc..287599bbde98b2 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3569,6 +3569,8 @@ typedef struct { Py_ssize_t cnt; } repeatobject; +#define repeatobject_CAST(op) ((repeatobject *)(op)) + static PyObject * repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3596,8 +3598,9 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static void -repeat_dealloc(repeatobject *ro) +repeat_dealloc(PyObject *op) { + repeatobject *ro = repeatobject_CAST(op); PyTypeObject *tp = Py_TYPE(ro); PyObject_GC_UnTrack(ro); Py_XDECREF(ro->element); @@ -3606,16 +3609,18 @@ repeat_dealloc(repeatobject *ro) } static int -repeat_traverse(repeatobject *ro, visitproc visit, void *arg) +repeat_traverse(PyObject *op, visitproc visit, void *arg) { + repeatobject *ro = repeatobject_CAST(op); Py_VISIT(Py_TYPE(ro)); Py_VISIT(ro->element); return 0; } static PyObject * -repeat_next(repeatobject *ro) +repeat_next(PyObject *op) { + repeatobject *ro = repeatobject_CAST(op); if (ro->cnt == 0) return NULL; if (ro->cnt > 0) @@ -3624,8 +3629,9 @@ repeat_next(repeatobject *ro) } static PyObject * -repeat_repr(repeatobject *ro) +repeat_repr(PyObject *op) { + repeatobject *ro = repeatobject_CAST(op); if (ro->cnt == -1) return PyUnicode_FromFormat("%s(%R)", _PyType_Name(Py_TYPE(ro)), ro->element); @@ -3636,8 +3642,9 @@ repeat_repr(repeatobject *ro) } static PyObject * -repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored)) +repeat_len(PyObject *op, PyObject *Py_UNUSED(args)) { + repeatobject *ro = repeatobject_CAST(op); if (ro->cnt == -1) { PyErr_SetString(PyExc_TypeError, "len() of unsized object"); return NULL; @@ -3648,7 +3655,7 @@ repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyMethodDef repeat_methods[] = { - {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc}, + {"__length_hint__", repeat_len, METH_NOARGS, length_hint_doc}, {NULL, NULL} /* sentinel */ }; From b6ebab37e02397122c8ea3c0158948f922d028c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 14:02:36 +0100 Subject: [PATCH 22/23] fix UBSan failures for `ziplongestobject` --- Modules/itertoolsmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 287599bbde98b2..9d260bd6bdda01 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3698,6 +3698,8 @@ typedef struct { PyObject *fillvalue; } ziplongestobject; +#define ziplongestobject_CAST(op) ((ziplongestobject *)(op)) + static PyObject * zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3767,8 +3769,9 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static void -zip_longest_dealloc(ziplongestobject *lz) +zip_longest_dealloc(PyObject *op) { + ziplongestobject *lz = ziplongestobject_CAST(op); PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); @@ -3779,8 +3782,9 @@ zip_longest_dealloc(ziplongestobject *lz) } static int -zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) +zip_longest_traverse(PyObject *op, visitproc visit, void *arg) { + ziplongestobject *lz = ziplongestobject_CAST(op); Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->ittuple); Py_VISIT(lz->result); @@ -3789,8 +3793,9 @@ zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) } static PyObject * -zip_longest_next(ziplongestobject *lz) +zip_longest_next(PyObject *op) { + ziplongestobject *lz = ziplongestobject_CAST(op); Py_ssize_t i; Py_ssize_t tuplesize = lz->tuplesize; PyObject *result = lz->result; From b94e7c52ad3b7a8c20ec942b014f643176158444 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 18 Feb 2025 14:47:12 +0100 Subject: [PATCH 23/23] Restore a cast --- Modules/itertoolsmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 9d260bd6bdda01..3e425ee5f92dcd 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -929,7 +929,7 @@ tee_traverse(PyObject *op, visitproc visit, void *arg) { teeobject *to = teeobject_CAST(op); Py_VISIT(Py_TYPE(to)); - Py_VISIT(to->dataobj); + Py_VISIT((PyObject *)to->dataobj); return 0; }