https://github.com/python/cpython/commit/ead091357d67bc8144a73fcb7cb367602d21ecdd commit: ead091357d67bc8144a73fcb7cb367602d21ecdd branch: main author: Bénédikt Tran <10796600+picn...@users.noreply.github.com> committer: encukou <encu...@gmail.com> date: 2025-02-25T13:02:32+01:00 summary:
gh-111178: fix UBSan failures in `Modules/xx*.c` (GH-129797) Fix UBSan failures in `Modules/xxlimited.c`, `Modules/xxlimited_35.c`, `Modules/xxsubtype.c`, `Modules/xxmodule.c` files: M Modules/xxlimited.c M Modules/xxlimited_35.c M Modules/xxmodule.c M Modules/xxsubtype.c diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index d86741e1dfc18c..26ac35734fb060 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -90,6 +90,7 @@ typedef struct { Py_ssize_t x_exports; /* how many buffer are exported */ } XxoObject; +#define XxoObject_CAST(op) ((XxoObject *)(op)) // XXX: no good way to do this yet // #define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) @@ -114,28 +115,29 @@ newXxoObject(PyObject *module) /* Xxo finalization */ static int -Xxo_traverse(PyObject *self_obj, visitproc visit, void *arg) +Xxo_traverse(PyObject *op, visitproc visit, void *arg) { // Visit the type - Py_VISIT(Py_TYPE(self_obj)); + Py_VISIT(Py_TYPE(op)); // Visit the attribute dict - XxoObject *self = (XxoObject *)self_obj; + XxoObject *self = XxoObject_CAST(op); Py_VISIT(self->x_attr); return 0; } static int -Xxo_clear(XxoObject *self) +Xxo_clear(PyObject *op) { + XxoObject *self = XxoObject_CAST(op); Py_CLEAR(self->x_attr); return 0; } static void -Xxo_finalize(PyObject *self_obj) +Xxo_finalize(PyObject *op) { - XxoObject *self = (XxoObject *)self_obj; + XxoObject *self = XxoObject_CAST(op); Py_CLEAR(self->x_attr); } @@ -154,8 +156,9 @@ Xxo_dealloc(PyObject *self) /* Xxo attribute handling */ static PyObject * -Xxo_getattro(XxoObject *self, PyObject *name) +Xxo_getattro(PyObject *op, PyObject *name) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { @@ -165,12 +168,13 @@ Xxo_getattro(XxoObject *self, PyObject *name) return NULL; } } - return PyObject_GenericGetAttr((PyObject *)self, name); + return PyObject_GenericGetAttr(op, name); } static int -Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v) +Xxo_setattro(PyObject *op, PyObject *name, PyObject *v) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr == NULL) { // prepare the attribute dict self->x_attr = PyDict_New(); @@ -197,8 +201,8 @@ Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v) /* Xxo methods */ static PyObject * -Xxo_demo(XxoObject *self, PyTypeObject *defining_class, - PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +Xxo_demo(PyObject *op, PyTypeObject *defining_class, + PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { if (kwnames != NULL && PyObject_Length(kwnames)) { PyErr_SetString(PyExc_TypeError, "demo() takes no keyword arguments"); @@ -233,9 +237,10 @@ static PyMethodDef Xxo_methods[] = { /* Xxo buffer interface */ static int -Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags) +Xxo_getbuffer(PyObject *op, Py_buffer *view, int flags) { - int res = PyBuffer_FillInfo(view, (PyObject*)self, + XxoObject *self = XxoObject_CAST(op); + int res = PyBuffer_FillInfo(view, op, (void *)self->x_buffer, BUFSIZE, 0, flags); if (res == 0) { @@ -245,14 +250,16 @@ Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags) } static void -Xxo_releasebuffer(XxoObject *self, Py_buffer *view) +Xxo_releasebuffer(PyObject *op, Py_buffer *Py_UNUSED(view)) { + XxoObject *self = XxoObject_CAST(op); self->x_exports--; } static PyObject * -Xxo_get_x_exports(XxoObject *self, void *c) +Xxo_get_x_exports(PyObject *op, void *Py_UNUSED(closure)) { + XxoObject *self = XxoObject_CAST(op); return PyLong_FromSsize_t(self->x_exports); } @@ -262,7 +269,7 @@ PyDoc_STRVAR(Xxo_doc, "A class that explicitly stores attributes in an internal dict"); static PyGetSetDef Xxo_getsetlist[] = { - {"x_exports", (getter) Xxo_get_x_exports, NULL, NULL}, + {"x_exports", Xxo_get_x_exports, NULL, NULL}, {NULL}, }; diff --git a/Modules/xxlimited_35.c b/Modules/xxlimited_35.c index 1063e54217b746..48fd1aac3f0f8d 100644 --- a/Modules/xxlimited_35.c +++ b/Modules/xxlimited_35.c @@ -24,7 +24,8 @@ typedef struct { static PyObject *Xxo_Type; -#define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) +#define XxoObject_CAST(op) ((XxoObject *)(op)) +#define XxoObject_Check(v) Py_IS_TYPE(v, Xxo_Type) static XxoObject * newXxoObject(PyObject *arg) @@ -40,32 +41,36 @@ newXxoObject(PyObject *arg) /* Xxo methods */ static int -Xxo_traverse(XxoObject *self, visitproc visit, void *arg) +Xxo_traverse(PyObject *op, visitproc visit, void *arg) { + XxoObject *self = XxoObject_CAST(op); Py_VISIT(Py_TYPE(self)); Py_VISIT(self->x_attr); return 0; } static int -Xxo_clear(XxoObject *self) +Xxo_clear(PyObject *op) { + XxoObject *self = XxoObject_CAST(op); Py_CLEAR(self->x_attr); return 0; } static void -Xxo_finalize(XxoObject *self) +Xxo_finalize(PyObject *op) { + XxoObject *self = XxoObject_CAST(op); Py_CLEAR(self->x_attr); } static PyObject * -Xxo_demo(XxoObject *self, PyObject *args) +Xxo_demo(PyObject *self, PyObject *args) { PyObject *o = NULL; - if (!PyArg_ParseTuple(args, "|O:demo", &o)) + if (!PyArg_ParseTuple(args, "|O:demo", &o)) { return NULL; + } /* Test availability of fast type checks */ if (o != NULL && PyUnicode_Check(o)) { return Py_NewRef(o); @@ -74,14 +79,14 @@ Xxo_demo(XxoObject *self, PyObject *args) } static PyMethodDef Xxo_methods[] = { - {"demo", (PyCFunction)Xxo_demo, METH_VARARGS, - PyDoc_STR("demo() -> None")}, - {NULL, NULL} /* sentinel */ + {"demo", Xxo_demo, METH_VARARGS, PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ }; static PyObject * -Xxo_getattro(XxoObject *self, PyObject *name) +Xxo_getattro(PyObject *op, PyObject *name) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { @@ -91,26 +96,28 @@ Xxo_getattro(XxoObject *self, PyObject *name) return NULL; } } - return PyObject_GenericGetAttr((PyObject *)self, name); + return PyObject_GenericGetAttr(op, name); } static int -Xxo_setattr(XxoObject *self, const char *name, PyObject *v) +Xxo_setattr(PyObject *op, const char *name, PyObject *v) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr == NULL) { self->x_attr = PyDict_New(); - if (self->x_attr == NULL) + if (self->x_attr == NULL) { return -1; + } } if (v == NULL) { int rv = PyDict_DelItemString(self->x_attr, name); - if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_SetString(PyExc_AttributeError, - "delete non-existing Xxo attribute"); + "delete non-existing Xxo attribute"); + } return rv; } - else - return PyDict_SetItemString(self->x_attr, name, v); + return PyDict_SetItemString(self->x_attr, name, v); } static PyType_Slot Xxo_Type_slots[] = { diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index a46bf8f0e64ee2..1a21aa90b2a4c6 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -25,15 +25,16 @@ typedef struct { static PyTypeObject Xxo_Type; -#define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type) +#define XxoObject_CAST(op) ((XxoObject *)(op)) +#define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type) static XxoObject * newXxoObject(PyObject *arg) { - XxoObject *self; - self = PyObject_New(XxoObject, &Xxo_Type); - if (self == NULL) + XxoObject *self = PyObject_New(XxoObject, &Xxo_Type); + if (self == NULL) { return NULL; + } self->x_attr = NULL; return self; } @@ -41,29 +42,31 @@ newXxoObject(PyObject *arg) /* Xxo methods */ static void -Xxo_dealloc(XxoObject *self) +Xxo_dealloc(PyObject *op) { + XxoObject *self = XxoObject_CAST(op); Py_XDECREF(self->x_attr); PyObject_Free(self); } static PyObject * -Xxo_demo(XxoObject *self, PyObject *args) +Xxo_demo(PyObject *Py_UNUSED(op), PyObject *args) { - if (!PyArg_ParseTuple(args, ":demo")) + if (!PyArg_ParseTuple(args, ":demo")) { return NULL; + } return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { - {"demo", (PyCFunction)Xxo_demo, METH_VARARGS, - PyDoc_STR("demo() -> None")}, - {NULL, NULL} /* sentinel */ + {"demo", Xxo_demo, METH_VARARGS, PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ }; static PyObject * -Xxo_getattro(XxoObject *self, PyObject *name) +Xxo_getattro(PyObject *op, PyObject *name) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { @@ -73,26 +76,28 @@ Xxo_getattro(XxoObject *self, PyObject *name) return NULL; } } - return PyObject_GenericGetAttr((PyObject *)self, name); + return PyObject_GenericGetAttr(op, name); } static int -Xxo_setattr(XxoObject *self, const char *name, PyObject *v) +Xxo_setattr(PyObject *op, const char *name, PyObject *v) { + XxoObject *self = XxoObject_CAST(op); if (self->x_attr == NULL) { self->x_attr = PyDict_New(); - if (self->x_attr == NULL) + if (self->x_attr == NULL) { return -1; + } } if (v == NULL) { int rv = PyDict_DelItemString(self->x_attr, name); - if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_SetString(PyExc_AttributeError, - "delete non-existing Xxo attribute"); + "delete non-existing Xxo attribute"); + } return rv; } - else - return PyDict_SetItemString(self->x_attr, name, v); + return PyDict_SetItemString(self->x_attr, name, v); } static PyTypeObject Xxo_Type = { @@ -103,10 +108,10 @@ static PyTypeObject Xxo_Type = { sizeof(XxoObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ - (destructor)Xxo_dealloc, /*tp_dealloc*/ + Xxo_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)Xxo_setattr, /*tp_setattr*/ + 0, /*tp_getattr*/ + Xxo_setattr, /*tp_setattr*/ 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ @@ -115,7 +120,7 @@ static PyTypeObject Xxo_Type = { 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - (getattrofunc)Xxo_getattro, /*tp_getattro*/ + Xxo_getattro, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c index 9c548f44558d41..a8a1417f40efef 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -26,21 +26,26 @@ typedef struct { int state; } spamlistobject; +#define _spamlistobject_CAST(op) ((spamlistobject *)(op)) + static PyObject * -spamlist_getstate(spamlistobject *self, PyObject *args) +spamlist_getstate(PyObject *op, PyObject *args) { - if (!PyArg_ParseTuple(args, ":getstate")) + if (!PyArg_ParseTuple(args, ":getstate")) { return NULL; + } + spamlistobject *self = _spamlistobject_CAST(op); return PyLong_FromLong(self->state); } static PyObject * -spamlist_setstate(spamlistobject *self, PyObject *args) +spamlist_setstate(PyObject *op, PyObject *args) { int state; - - if (!PyArg_ParseTuple(args, "i:setstate", &state)) + if (!PyArg_ParseTuple(args, "i:setstate", &state)) { return NULL; + } + spamlistobject *self = _spamlistobject_CAST(op); self->state = state; return Py_NewRef(Py_None); } @@ -63,9 +68,9 @@ spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw) } static PyMethodDef spamlist_methods[] = { - {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS, + {"getstate", spamlist_getstate, METH_VARARGS, PyDoc_STR("getstate() -> state")}, - {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS, + {"setstate", spamlist_setstate, METH_VARARGS, PyDoc_STR("setstate(state)")}, /* These entries differ only in the flags; they are used by the tests in test.test_descr. */ @@ -79,22 +84,25 @@ static PyMethodDef spamlist_methods[] = { }; static int -spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds) +spamlist_init(PyObject *op, PyObject *args, PyObject *kwds) { - if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0) + if (PyList_Type.tp_init(op, args, kwds) < 0) { return -1; + } + spamlistobject *self = _spamlistobject_CAST(op); self->state = 0; return 0; } static PyObject * -spamlist_state_get(spamlistobject *self, void *Py_UNUSED(ignored)) +spamlist_state_get(PyObject *op, void *Py_UNUSED(closure)) { + spamlistobject *self = _spamlistobject_CAST(op); return PyLong_FromLong(self->state); } static PyGetSetDef spamlist_getsets[] = { - {"state", (getter)spamlist_state_get, NULL, + {"state", spamlist_state_get, NULL, PyDoc_STR("an int variable for demonstration purposes")}, {0} }; @@ -135,7 +143,7 @@ static PyTypeObject spamlist_type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)spamlist_init, /* tp_init */ + spamlist_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; @@ -147,38 +155,46 @@ typedef struct { int state; } spamdictobject; +#define _spamdictobject_CAST(op) ((spamdictobject *)(op)) + static PyObject * -spamdict_getstate(spamdictobject *self, PyObject *args) +spamdict_getstate(PyObject *op, PyObject *args) { - if (!PyArg_ParseTuple(args, ":getstate")) + if (!PyArg_ParseTuple(args, ":getstate")) { return NULL; + } + spamdictobject *self = _spamdictobject_CAST(op); return PyLong_FromLong(self->state); } static PyObject * -spamdict_setstate(spamdictobject *self, PyObject *args) +spamdict_setstate(PyObject *op, PyObject *args) { int state; - - if (!PyArg_ParseTuple(args, "i:setstate", &state)) + if (!PyArg_ParseTuple(args, "i:setstate", &state)) { return NULL; + } + + spamdictobject *self = _spamdictobject_CAST(op); self->state = state; return Py_NewRef(Py_None); } static PyMethodDef spamdict_methods[] = { - {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS, + {"getstate", spamdict_getstate, METH_VARARGS, PyDoc_STR("getstate() -> state")}, - {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS, + {"setstate", spamdict_setstate, METH_VARARGS, PyDoc_STR("setstate(state)")}, {NULL, NULL}, }; static int -spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) +spamdict_init(PyObject *op, PyObject *args, PyObject *kwds) { - if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + if (PyDict_Type.tp_init(op, args, kwds) < 0) { return -1; + } + spamdictobject *self = _spamdictobject_CAST(op); self->state = 0; return 0; } @@ -225,7 +241,7 @@ static PyTypeObject spamdict_type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)spamdict_init, /* tp_init */ + spamdict_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com