mirror of
https://github.com/python/cpython.git
synced 2025-11-29 06:22:10 +00:00
gh-111178: fix UBSan failures in Objects/enumobject.c (GH-128246)
* fix UBSan failures for `enumobject` * fix UBSan failures for `reversedobject`
This commit is contained in:
parent
621d4ff35e
commit
aad5ba4b6a
1 changed files with 35 additions and 22 deletions
|
|
@ -23,6 +23,7 @@ typedef struct {
|
||||||
PyObject* one; /* borrowed reference */
|
PyObject* one; /* borrowed reference */
|
||||||
} enumobject;
|
} enumobject;
|
||||||
|
|
||||||
|
#define _enumobject_CAST(op) ((enumobject *)(op))
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -150,8 +151,9 @@ enumerate_vectorcall(PyObject *type, PyObject *const *args,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enum_dealloc(enumobject *en)
|
enum_dealloc(PyObject *op)
|
||||||
{
|
{
|
||||||
|
enumobject *en = _enumobject_CAST(op);
|
||||||
PyObject_GC_UnTrack(en);
|
PyObject_GC_UnTrack(en);
|
||||||
Py_XDECREF(en->en_sit);
|
Py_XDECREF(en->en_sit);
|
||||||
Py_XDECREF(en->en_result);
|
Py_XDECREF(en->en_result);
|
||||||
|
|
@ -160,8 +162,9 @@ enum_dealloc(enumobject *en)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
enum_traverse(enumobject *en, visitproc visit, void *arg)
|
enum_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
enumobject *en = _enumobject_CAST(op);
|
||||||
Py_VISIT(en->en_sit);
|
Py_VISIT(en->en_sit);
|
||||||
Py_VISIT(en->en_result);
|
Py_VISIT(en->en_result);
|
||||||
Py_VISIT(en->en_longindex);
|
Py_VISIT(en->en_longindex);
|
||||||
|
|
@ -220,8 +223,9 @@ enum_next_long(enumobject *en, PyObject* next_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
enum_next(enumobject *en)
|
enum_next(PyObject *op)
|
||||||
{
|
{
|
||||||
|
enumobject *en = _enumobject_CAST(op);
|
||||||
PyObject *next_index;
|
PyObject *next_index;
|
||||||
PyObject *next_item;
|
PyObject *next_item;
|
||||||
PyObject *result = en->en_result;
|
PyObject *result = en->en_result;
|
||||||
|
|
@ -270,8 +274,9 @@ enum_next(enumobject *en)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored))
|
enum_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
enumobject *en = _enumobject_CAST(op);
|
||||||
if (en->en_longindex != NULL)
|
if (en->en_longindex != NULL)
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex);
|
return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex);
|
||||||
else
|
else
|
||||||
|
|
@ -281,7 +286,7 @@ enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored))
|
||||||
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
||||||
|
|
||||||
static PyMethodDef enum_methods[] = {
|
static PyMethodDef enum_methods[] = {
|
||||||
{"__reduce__", (PyCFunction)enum_reduce, METH_NOARGS, reduce_doc},
|
{"__reduce__", enum_reduce, METH_NOARGS, reduce_doc},
|
||||||
{"__class_getitem__", Py_GenericAlias,
|
{"__class_getitem__", Py_GenericAlias,
|
||||||
METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
|
METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
|
|
@ -293,7 +298,7 @@ PyTypeObject PyEnum_Type = {
|
||||||
sizeof(enumobject), /* tp_basicsize */
|
sizeof(enumobject), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)enum_dealloc, /* tp_dealloc */
|
enum_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_vectorcall_offset */
|
0, /* tp_vectorcall_offset */
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
|
|
@ -311,12 +316,12 @@ PyTypeObject PyEnum_Type = {
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
enum_new__doc__, /* tp_doc */
|
enum_new__doc__, /* tp_doc */
|
||||||
(traverseproc)enum_traverse, /* tp_traverse */
|
enum_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)enum_next, /* tp_iternext */
|
enum_next, /* tp_iternext */
|
||||||
enum_methods, /* tp_methods */
|
enum_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
|
|
@ -329,7 +334,7 @@ PyTypeObject PyEnum_Type = {
|
||||||
PyType_GenericAlloc, /* tp_alloc */
|
PyType_GenericAlloc, /* tp_alloc */
|
||||||
enum_new, /* tp_new */
|
enum_new, /* tp_new */
|
||||||
PyObject_GC_Del, /* tp_free */
|
PyObject_GC_Del, /* tp_free */
|
||||||
.tp_vectorcall = (vectorcallfunc)enumerate_vectorcall
|
.tp_vectorcall = enumerate_vectorcall
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Reversed Object ***************************************************************/
|
/* Reversed Object ***************************************************************/
|
||||||
|
|
@ -340,6 +345,8 @@ typedef struct {
|
||||||
PyObject* seq;
|
PyObject* seq;
|
||||||
} reversedobject;
|
} reversedobject;
|
||||||
|
|
||||||
|
#define _reversedobject_CAST(op) ((reversedobject *)(op))
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
@classmethod
|
@classmethod
|
||||||
reversed.__new__ as reversed_new
|
reversed.__new__ as reversed_new
|
||||||
|
|
@ -411,23 +418,26 @@ reversed_vectorcall(PyObject *type, PyObject * const*args,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reversed_dealloc(reversedobject *ro)
|
reversed_dealloc(PyObject *op)
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
PyObject_GC_UnTrack(ro);
|
PyObject_GC_UnTrack(ro);
|
||||||
Py_XDECREF(ro->seq);
|
Py_XDECREF(ro->seq);
|
||||||
Py_TYPE(ro)->tp_free(ro);
|
Py_TYPE(ro)->tp_free(ro);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
|
reversed_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
Py_VISIT(ro->seq);
|
Py_VISIT(ro->seq);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_next(reversedobject *ro)
|
reversed_next(PyObject *op)
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
Py_ssize_t index = ro->index;
|
Py_ssize_t index = ro->index;
|
||||||
|
|
||||||
|
|
@ -447,8 +457,9 @@ reversed_next(reversedobject *ro)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored))
|
reversed_len(PyObject *op, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
Py_ssize_t position, seqsize;
|
Py_ssize_t position, seqsize;
|
||||||
|
|
||||||
if (ro->seq == NULL)
|
if (ro->seq == NULL)
|
||||||
|
|
@ -463,8 +474,9 @@ reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored))
|
||||||
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
|
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored))
|
reversed_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
if (ro->seq)
|
if (ro->seq)
|
||||||
return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index);
|
return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index);
|
||||||
else
|
else
|
||||||
|
|
@ -472,8 +484,9 @@ reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_setstate(reversedobject *ro, PyObject *state)
|
reversed_setstate(PyObject *op, PyObject *state)
|
||||||
{
|
{
|
||||||
|
reversedobject *ro = _reversedobject_CAST(op);
|
||||||
Py_ssize_t index = PyLong_AsSsize_t(state);
|
Py_ssize_t index = PyLong_AsSsize_t(state);
|
||||||
if (index == -1 && PyErr_Occurred())
|
if (index == -1 && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -493,9 +506,9 @@ reversed_setstate(reversedobject *ro, PyObject *state)
|
||||||
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
|
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
|
||||||
|
|
||||||
static PyMethodDef reversediter_methods[] = {
|
static PyMethodDef reversediter_methods[] = {
|
||||||
{"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
|
{"__length_hint__", reversed_len, METH_NOARGS, length_hint_doc},
|
||||||
{"__reduce__", (PyCFunction)reversed_reduce, METH_NOARGS, reduce_doc},
|
{"__reduce__", reversed_reduce, METH_NOARGS, reduce_doc},
|
||||||
{"__setstate__", (PyCFunction)reversed_setstate, METH_O, setstate_doc},
|
{"__setstate__", reversed_setstate, METH_O, setstate_doc},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -505,7 +518,7 @@ PyTypeObject PyReversed_Type = {
|
||||||
sizeof(reversedobject), /* tp_basicsize */
|
sizeof(reversedobject), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)reversed_dealloc, /* tp_dealloc */
|
reversed_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_vectorcall_offset */
|
0, /* tp_vectorcall_offset */
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
|
|
@ -523,12 +536,12 @@ PyTypeObject PyReversed_Type = {
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
reversed_new__doc__, /* tp_doc */
|
reversed_new__doc__, /* tp_doc */
|
||||||
(traverseproc)reversed_traverse,/* tp_traverse */
|
reversed_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)reversed_next, /* tp_iternext */
|
reversed_next, /* tp_iternext */
|
||||||
reversediter_methods, /* tp_methods */
|
reversediter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
|
|
@ -541,5 +554,5 @@ PyTypeObject PyReversed_Type = {
|
||||||
PyType_GenericAlloc, /* tp_alloc */
|
PyType_GenericAlloc, /* tp_alloc */
|
||||||
reversed_new, /* tp_new */
|
reversed_new, /* tp_new */
|
||||||
PyObject_GC_Del, /* tp_free */
|
PyObject_GC_Del, /* tp_free */
|
||||||
.tp_vectorcall = (vectorcallfunc)reversed_vectorcall,
|
.tp_vectorcall = reversed_vectorcall,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue