Skip to content

Commit 3a9cc21

Browse files
committed
fix UBSan failures for PyStructObject
1 parent cf0b2da commit 3a9cc21

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

Modules/_struct.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ typedef struct {
7373
PyObject *weakreflist; /* List of weak references */
7474
} PyStructObject;
7575

76-
#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)
76+
#define _PyStructObject_CAST(op) ((PyStructObject *)(op))
77+
#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)
7778

7879
/* Define various structs to figure out the alignments of types */
7980

@@ -1853,33 +1854,36 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
18531854
}
18541855

18551856
static int
1856-
s_clear(PyStructObject *s)
1857+
s_clear(PyObject *op)
18571858
{
1859+
PyStructObject *s = _PyStructObject_CAST(op);
18581860
Py_CLEAR(s->s_format);
18591861
return 0;
18601862
}
18611863

18621864
static int
1863-
s_traverse(PyStructObject *s, visitproc visit, void *arg)
1865+
s_traverse(PyObject *op, visitproc visit, void *arg)
18641866
{
1867+
PyStructObject *s = _PyStructObject_CAST(op);
18651868
Py_VISIT(Py_TYPE(s));
18661869
Py_VISIT(s->s_format);
18671870
return 0;
18681871
}
18691872

18701873
static void
1871-
s_dealloc(PyStructObject *s)
1874+
s_dealloc(PyObject *op)
18721875
{
1876+
PyStructObject *s = _PyStructObject_CAST(op);
18731877
PyTypeObject *tp = Py_TYPE(s);
18741878
PyObject_GC_UnTrack(s);
1875-
if (s->weakreflist != NULL)
1876-
PyObject_ClearWeakRefs((PyObject *)s);
1879+
if (s->weakreflist != NULL) {
1880+
PyObject_ClearWeakRefs(op);
1881+
}
18771882
if (s->s_codes != NULL) {
18781883
PyMem_Free(s->s_codes);
18791884
}
18801885
Py_XDECREF(s->s_format);
1881-
freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1882-
free_func(s);
1886+
tp->tp_free(s);
18831887
Py_DECREF(tp);
18841888
}
18851889

@@ -2264,7 +2268,7 @@ s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
22642268
_structmodulestate *state = get_struct_state_structinst(self);
22652269

22662270
/* Validate arguments. */
2267-
soself = (PyStructObject *)self;
2271+
soself = _PyStructObject_CAST(self);
22682272
assert(PyStruct_Check(self, state));
22692273
assert(soself->s_codes != NULL);
22702274
if (nargs != soself->s_len)
@@ -2309,7 +2313,7 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
23092313
_structmodulestate *state = get_struct_state_structinst(self);
23102314

23112315
/* Validate arguments. +1 is for the first arg as buffer. */
2312-
soself = (PyStructObject *)self;
2316+
soself = _PyStructObject_CAST(self);
23132317
assert(PyStruct_Check(self, state));
23142318
assert(soself->s_codes != NULL);
23152319
if (nargs != (soself->s_len + 2))
@@ -2395,24 +2399,27 @@ s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
23952399
}
23962400

23972401
static PyObject *
2398-
s_get_format(PyStructObject *self, void *unused)
2402+
s_get_format(PyObject *op, void *Py_UNUSED(closure))
23992403
{
2404+
PyStructObject *self = _PyStructObject_CAST(op);
24002405
return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
24012406
PyBytes_GET_SIZE(self->s_format));
24022407
}
24032408

24042409
static PyObject *
2405-
s_get_size(PyStructObject *self, void *unused)
2410+
s_get_size(PyObject *op, void *Py_UNUSED(closure))
24062411
{
2412+
PyStructObject *self = _PyStructObject_CAST(op);
24072413
return PyLong_FromSsize_t(self->s_size);
24082414
}
24092415

24102416
PyDoc_STRVAR(s_sizeof__doc__,
24112417
"S.__sizeof__() -> size of S in memory, in bytes");
24122418

24132419
static PyObject *
2414-
s_sizeof(PyStructObject *self, void *unused)
2420+
s_sizeof(PyObject *op, PyObject *Py_UNUSED(unused))
24152421
{
2422+
PyStructObject *self = _PyStructObject_CAST(op);
24162423
size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
24172424
for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) {
24182425
size += sizeof(formatcode);
@@ -2421,8 +2428,9 @@ s_sizeof(PyStructObject *self, void *unused)
24212428
}
24222429

24232430
static PyObject *
2424-
s_repr(PyStructObject *self)
2431+
s_repr(PyObject *op)
24252432
{
2433+
PyStructObject *self = _PyStructObject_CAST(op);
24262434
PyObject* fmt = PyUnicode_FromStringAndSize(
24272435
PyBytes_AS_STRING(self->s_format), PyBytes_GET_SIZE(self->s_format));
24282436
if (fmt == NULL) {
@@ -2441,7 +2449,7 @@ static struct PyMethodDef s_methods[] = {
24412449
{"pack_into", _PyCFunction_CAST(s_pack_into), METH_FASTCALL, s_pack_into__doc__},
24422450
STRUCT_UNPACK_METHODDEF
24432451
STRUCT_UNPACK_FROM_METHODDEF
2444-
{"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
2452+
{"__sizeof__", s_sizeof, METH_NOARGS, s_sizeof__doc__},
24452453
{NULL, NULL} /* sentinel */
24462454
};
24472455

@@ -2451,8 +2459,8 @@ static PyMemberDef s_members[] = {
24512459
};
24522460

24532461
static PyGetSetDef s_getsetlist[] = {
2454-
{"format", (getter)s_get_format, (setter)NULL, PyDoc_STR("struct format string"), NULL},
2455-
{"size", (getter)s_get_size, (setter)NULL, PyDoc_STR("struct size in bytes"), NULL},
2462+
{"format", s_get_format, NULL, PyDoc_STR("struct format string"), NULL},
2463+
{"size", s_get_size, NULL, PyDoc_STR("struct size in bytes"), NULL},
24562464
{NULL} /* sentinel */
24572465
};
24582466

@@ -2508,7 +2516,7 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
25082516
return 0;
25092517
}
25102518
if (s_object != NULL) {
2511-
*ptr = (PyStructObject *)s_object;
2519+
*ptr = _PyStructObject_CAST(s_object);
25122520
return Py_CLEANUP_SUPPORTED;
25132521
}
25142522

0 commit comments

Comments
 (0)