Skip to content

Commit 613240b

Browse files
authored
gh-111178: fix UBSan failures in Objects/bytearrayobject.c (GH-128236)
* fix UBSan failures for `bytesiterobject` * fix UBSan failures for `PyByteArrayObject`
1 parent 295776c commit 613240b

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

Objects/bytearrayobject.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,8 +2113,9 @@ PyDoc_STRVAR(alloc_doc,
21132113
Return the number of bytes actually allocated.");
21142114

21152115
static PyObject *
2116-
bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
2116+
bytearray_alloc(PyObject *op, PyObject *Py_UNUSED(ignored))
21172117
{
2118+
PyByteArrayObject *self = _PyByteArray_CAST(op);
21182119
return PyLong_FromSsize_t(self->ob_alloc);
21192120
}
21202121

@@ -2313,7 +2314,7 @@ static PyBufferProcs bytearray_as_buffer = {
23132314
};
23142315

23152316
static PyMethodDef bytearray_methods[] = {
2316-
{"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2317+
{"__alloc__", bytearray_alloc, METH_NOARGS, alloc_doc},
23172318
BYTEARRAY_REDUCE_METHODDEF
23182319
BYTEARRAY_REDUCE_EX_METHODDEF
23192320
BYTEARRAY_SIZEOF_METHODDEF
@@ -2464,24 +2465,29 @@ typedef struct {
24642465
PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
24652466
} bytesiterobject;
24662467

2468+
#define _bytesiterobject_CAST(op) ((bytesiterobject *)(op))
2469+
24672470
static void
2468-
bytearrayiter_dealloc(bytesiterobject *it)
2471+
bytearrayiter_dealloc(PyObject *self)
24692472
{
2473+
bytesiterobject *it = _bytesiterobject_CAST(self);
24702474
_PyObject_GC_UNTRACK(it);
24712475
Py_XDECREF(it->it_seq);
24722476
PyObject_GC_Del(it);
24732477
}
24742478

24752479
static int
2476-
bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2480+
bytearrayiter_traverse(PyObject *self, visitproc visit, void *arg)
24772481
{
2482+
bytesiterobject *it = _bytesiterobject_CAST(self);
24782483
Py_VISIT(it->it_seq);
24792484
return 0;
24802485
}
24812486

24822487
static PyObject *
2483-
bytearrayiter_next(bytesiterobject *it)
2488+
bytearrayiter_next(PyObject *self)
24842489
{
2490+
bytesiterobject *it = _bytesiterobject_CAST(self);
24852491
PyByteArrayObject *seq;
24862492

24872493
assert(it != NULL);
@@ -2501,8 +2507,9 @@ bytearrayiter_next(bytesiterobject *it)
25012507
}
25022508

25032509
static PyObject *
2504-
bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2510+
bytearrayiter_length_hint(PyObject *self, PyObject *Py_UNUSED(ignored))
25052511
{
2512+
bytesiterobject *it = _bytesiterobject_CAST(self);
25062513
Py_ssize_t len = 0;
25072514
if (it->it_seq) {
25082515
len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
@@ -2517,14 +2524,14 @@ PyDoc_STRVAR(length_hint_doc,
25172524
"Private method returning an estimate of len(list(it)).");
25182525

25192526
static PyObject *
2520-
bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2527+
bytearrayiter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
25212528
{
25222529
PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
25232530

25242531
/* _PyEval_GetBuiltin can invoke arbitrary code,
25252532
* call must be before access of iterator pointers.
25262533
* see issue #101765 */
2527-
2534+
bytesiterobject *it = _bytesiterobject_CAST(self);
25282535
if (it->it_seq != NULL) {
25292536
return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
25302537
} else {
@@ -2533,11 +2540,13 @@ bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
25332540
}
25342541

25352542
static PyObject *
2536-
bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2543+
bytearrayiter_setstate(PyObject *self, PyObject *state)
25372544
{
25382545
Py_ssize_t index = PyLong_AsSsize_t(state);
25392546
if (index == -1 && PyErr_Occurred())
25402547
return NULL;
2548+
2549+
bytesiterobject *it = _bytesiterobject_CAST(self);
25412550
if (it->it_seq != NULL) {
25422551
if (index < 0)
25432552
index = 0;
@@ -2551,11 +2560,11 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
25512560
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
25522561

25532562
static PyMethodDef bytearrayiter_methods[] = {
2554-
{"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
2563+
{"__length_hint__", bytearrayiter_length_hint, METH_NOARGS,
25552564
length_hint_doc},
2556-
{"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
2565+
{"__reduce__", bytearrayiter_reduce, METH_NOARGS,
25572566
bytearray_reduce__doc__},
2558-
{"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
2567+
{"__setstate__", bytearrayiter_setstate, METH_O,
25592568
setstate_doc},
25602569
{NULL, NULL} /* sentinel */
25612570
};
@@ -2566,7 +2575,7 @@ PyTypeObject PyByteArrayIter_Type = {
25662575
sizeof(bytesiterobject), /* tp_basicsize */
25672576
0, /* tp_itemsize */
25682577
/* methods */
2569-
(destructor)bytearrayiter_dealloc, /* tp_dealloc */
2578+
bytearrayiter_dealloc, /* tp_dealloc */
25702579
0, /* tp_vectorcall_offset */
25712580
0, /* tp_getattr */
25722581
0, /* tp_setattr */
@@ -2583,12 +2592,12 @@ PyTypeObject PyByteArrayIter_Type = {
25832592
0, /* tp_as_buffer */
25842593
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
25852594
0, /* tp_doc */
2586-
(traverseproc)bytearrayiter_traverse, /* tp_traverse */
2595+
bytearrayiter_traverse, /* tp_traverse */
25872596
0, /* tp_clear */
25882597
0, /* tp_richcompare */
25892598
0, /* tp_weaklistoffset */
25902599
PyObject_SelfIter, /* tp_iter */
2591-
(iternextfunc)bytearrayiter_next, /* tp_iternext */
2600+
bytearrayiter_next, /* tp_iternext */
25922601
bytearrayiter_methods, /* tp_methods */
25932602
0,
25942603
};

0 commit comments

Comments
 (0)