Skip to content

Commit aad5ba4

Browse files
authored
gh-111178: fix UBSan failures in Objects/enumobject.c (GH-128246)
* fix UBSan failures for `enumobject` * fix UBSan failures for `reversedobject`
1 parent 621d4ff commit aad5ba4

File tree

1 file changed

+35
-22
lines changed

1 file changed

+35
-22
lines changed

Objects/enumobject.c

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ typedef struct {
2323
PyObject* one; /* borrowed reference */
2424
} enumobject;
2525

26+
#define _enumobject_CAST(op) ((enumobject *)(op))
2627

2728
/*[clinic input]
2829
@classmethod
@@ -150,8 +151,9 @@ enumerate_vectorcall(PyObject *type, PyObject *const *args,
150151
}
151152

152153
static void
153-
enum_dealloc(enumobject *en)
154+
enum_dealloc(PyObject *op)
154155
{
156+
enumobject *en = _enumobject_CAST(op);
155157
PyObject_GC_UnTrack(en);
156158
Py_XDECREF(en->en_sit);
157159
Py_XDECREF(en->en_result);
@@ -160,8 +162,9 @@ enum_dealloc(enumobject *en)
160162
}
161163

162164
static int
163-
enum_traverse(enumobject *en, visitproc visit, void *arg)
165+
enum_traverse(PyObject *op, visitproc visit, void *arg)
164166
{
167+
enumobject *en = _enumobject_CAST(op);
165168
Py_VISIT(en->en_sit);
166169
Py_VISIT(en->en_result);
167170
Py_VISIT(en->en_longindex);
@@ -220,8 +223,9 @@ enum_next_long(enumobject *en, PyObject* next_item)
220223
}
221224

222225
static PyObject *
223-
enum_next(enumobject *en)
226+
enum_next(PyObject *op)
224227
{
228+
enumobject *en = _enumobject_CAST(op);
225229
PyObject *next_index;
226230
PyObject *next_item;
227231
PyObject *result = en->en_result;
@@ -270,8 +274,9 @@ enum_next(enumobject *en)
270274
}
271275

272276
static PyObject *
273-
enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored))
277+
enum_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
274278
{
279+
enumobject *en = _enumobject_CAST(op);
275280
if (en->en_longindex != NULL)
276281
return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex);
277282
else
@@ -281,7 +286,7 @@ enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored))
281286
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
282287

283288
static PyMethodDef enum_methods[] = {
284-
{"__reduce__", (PyCFunction)enum_reduce, METH_NOARGS, reduce_doc},
289+
{"__reduce__", enum_reduce, METH_NOARGS, reduce_doc},
285290
{"__class_getitem__", Py_GenericAlias,
286291
METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
287292
{NULL, NULL} /* sentinel */
@@ -293,7 +298,7 @@ PyTypeObject PyEnum_Type = {
293298
sizeof(enumobject), /* tp_basicsize */
294299
0, /* tp_itemsize */
295300
/* methods */
296-
(destructor)enum_dealloc, /* tp_dealloc */
301+
enum_dealloc, /* tp_dealloc */
297302
0, /* tp_vectorcall_offset */
298303
0, /* tp_getattr */
299304
0, /* tp_setattr */
@@ -311,12 +316,12 @@ PyTypeObject PyEnum_Type = {
311316
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
312317
Py_TPFLAGS_BASETYPE, /* tp_flags */
313318
enum_new__doc__, /* tp_doc */
314-
(traverseproc)enum_traverse, /* tp_traverse */
319+
enum_traverse, /* tp_traverse */
315320
0, /* tp_clear */
316321
0, /* tp_richcompare */
317322
0, /* tp_weaklistoffset */
318323
PyObject_SelfIter, /* tp_iter */
319-
(iternextfunc)enum_next, /* tp_iternext */
324+
enum_next, /* tp_iternext */
320325
enum_methods, /* tp_methods */
321326
0, /* tp_members */
322327
0, /* tp_getset */
@@ -329,7 +334,7 @@ PyTypeObject PyEnum_Type = {
329334
PyType_GenericAlloc, /* tp_alloc */
330335
enum_new, /* tp_new */
331336
PyObject_GC_Del, /* tp_free */
332-
.tp_vectorcall = (vectorcallfunc)enumerate_vectorcall
337+
.tp_vectorcall = enumerate_vectorcall
333338
};
334339

335340
/* Reversed Object ***************************************************************/
@@ -340,6 +345,8 @@ typedef struct {
340345
PyObject* seq;
341346
} reversedobject;
342347

348+
#define _reversedobject_CAST(op) ((reversedobject *)(op))
349+
343350
/*[clinic input]
344351
@classmethod
345352
reversed.__new__ as reversed_new
@@ -411,23 +418,26 @@ reversed_vectorcall(PyObject *type, PyObject * const*args,
411418
}
412419

413420
static void
414-
reversed_dealloc(reversedobject *ro)
421+
reversed_dealloc(PyObject *op)
415422
{
423+
reversedobject *ro = _reversedobject_CAST(op);
416424
PyObject_GC_UnTrack(ro);
417425
Py_XDECREF(ro->seq);
418426
Py_TYPE(ro)->tp_free(ro);
419427
}
420428

421429
static int
422-
reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
430+
reversed_traverse(PyObject *op, visitproc visit, void *arg)
423431
{
432+
reversedobject *ro = _reversedobject_CAST(op);
424433
Py_VISIT(ro->seq);
425434
return 0;
426435
}
427436

428437
static PyObject *
429-
reversed_next(reversedobject *ro)
438+
reversed_next(PyObject *op)
430439
{
440+
reversedobject *ro = _reversedobject_CAST(op);
431441
PyObject *item;
432442
Py_ssize_t index = ro->index;
433443

@@ -447,8 +457,9 @@ reversed_next(reversedobject *ro)
447457
}
448458

449459
static PyObject *
450-
reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored))
460+
reversed_len(PyObject *op, PyObject *Py_UNUSED(ignored))
451461
{
462+
reversedobject *ro = _reversedobject_CAST(op);
452463
Py_ssize_t position, seqsize;
453464

454465
if (ro->seq == NULL)
@@ -463,17 +474,19 @@ reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored))
463474
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
464475

465476
static PyObject *
466-
reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored))
477+
reversed_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
467478
{
479+
reversedobject *ro = _reversedobject_CAST(op);
468480
if (ro->seq)
469481
return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index);
470482
else
471483
return Py_BuildValue("O(())", Py_TYPE(ro));
472484
}
473485

474486
static PyObject *
475-
reversed_setstate(reversedobject *ro, PyObject *state)
487+
reversed_setstate(PyObject *op, PyObject *state)
476488
{
489+
reversedobject *ro = _reversedobject_CAST(op);
477490
Py_ssize_t index = PyLong_AsSsize_t(state);
478491
if (index == -1 && PyErr_Occurred())
479492
return NULL;
@@ -493,9 +506,9 @@ reversed_setstate(reversedobject *ro, PyObject *state)
493506
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
494507

495508
static PyMethodDef reversediter_methods[] = {
496-
{"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
497-
{"__reduce__", (PyCFunction)reversed_reduce, METH_NOARGS, reduce_doc},
498-
{"__setstate__", (PyCFunction)reversed_setstate, METH_O, setstate_doc},
509+
{"__length_hint__", reversed_len, METH_NOARGS, length_hint_doc},
510+
{"__reduce__", reversed_reduce, METH_NOARGS, reduce_doc},
511+
{"__setstate__", reversed_setstate, METH_O, setstate_doc},
499512
{NULL, NULL} /* sentinel */
500513
};
501514

@@ -505,7 +518,7 @@ PyTypeObject PyReversed_Type = {
505518
sizeof(reversedobject), /* tp_basicsize */
506519
0, /* tp_itemsize */
507520
/* methods */
508-
(destructor)reversed_dealloc, /* tp_dealloc */
521+
reversed_dealloc, /* tp_dealloc */
509522
0, /* tp_vectorcall_offset */
510523
0, /* tp_getattr */
511524
0, /* tp_setattr */
@@ -523,12 +536,12 @@ PyTypeObject PyReversed_Type = {
523536
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
524537
Py_TPFLAGS_BASETYPE, /* tp_flags */
525538
reversed_new__doc__, /* tp_doc */
526-
(traverseproc)reversed_traverse,/* tp_traverse */
539+
reversed_traverse, /* tp_traverse */
527540
0, /* tp_clear */
528541
0, /* tp_richcompare */
529542
0, /* tp_weaklistoffset */
530543
PyObject_SelfIter, /* tp_iter */
531-
(iternextfunc)reversed_next, /* tp_iternext */
544+
reversed_next, /* tp_iternext */
532545
reversediter_methods, /* tp_methods */
533546
0, /* tp_members */
534547
0, /* tp_getset */
@@ -541,5 +554,5 @@ PyTypeObject PyReversed_Type = {
541554
PyType_GenericAlloc, /* tp_alloc */
542555
reversed_new, /* tp_new */
543556
PyObject_GC_Del, /* tp_free */
544-
.tp_vectorcall = (vectorcallfunc)reversed_vectorcall,
557+
.tp_vectorcall = reversed_vectorcall,
545558
};

0 commit comments

Comments
 (0)