mirror of
https://github.com/python/cpython.git
synced 2025-12-11 03:20:01 +00:00
gh-111178: fix UBSan failures for anextawaitableobject (#131609)
This commit is contained in:
parent
b3319fe42f
commit
4efe397d8e
1 changed files with 29 additions and 15 deletions
|
|
@ -315,9 +315,12 @@ typedef struct {
|
||||||
PyObject *default_value;
|
PyObject *default_value;
|
||||||
} anextawaitableobject;
|
} anextawaitableobject;
|
||||||
|
|
||||||
|
#define anextawaitableobject_CAST(op) ((anextawaitableobject *)(op))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
anextawaitable_dealloc(anextawaitableobject *obj)
|
anextawaitable_dealloc(PyObject *op)
|
||||||
{
|
{
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
_PyObject_GC_UNTRACK(obj);
|
_PyObject_GC_UNTRACK(obj);
|
||||||
Py_XDECREF(obj->wrapped);
|
Py_XDECREF(obj->wrapped);
|
||||||
Py_XDECREF(obj->default_value);
|
Py_XDECREF(obj->default_value);
|
||||||
|
|
@ -325,8 +328,9 @@ anextawaitable_dealloc(anextawaitableobject *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg)
|
anextawaitable_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
Py_VISIT(obj->wrapped);
|
Py_VISIT(obj->wrapped);
|
||||||
Py_VISIT(obj->default_value);
|
Py_VISIT(obj->default_value);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -363,7 +367,7 @@ anextawaitable_getiter(anextawaitableobject *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
anextawaitable_iternext(anextawaitableobject *obj)
|
anextawaitable_iternext(PyObject *op)
|
||||||
{
|
{
|
||||||
/* Consider the following class:
|
/* Consider the following class:
|
||||||
*
|
*
|
||||||
|
|
@ -385,6 +389,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
|
||||||
* Then `await anext(gen)` can just call
|
* Then `await anext(gen)` can just call
|
||||||
* gen.__anext__().__next__()
|
* gen.__anext__().__next__()
|
||||||
*/
|
*/
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
PyObject *awaitable = anextawaitable_getiter(obj);
|
PyObject *awaitable = anextawaitable_getiter(obj);
|
||||||
if (awaitable == NULL) {
|
if (awaitable == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -403,11 +408,14 @@ anextawaitable_iternext(anextawaitableobject *obj)
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
|
anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg)
|
||||||
|
{
|
||||||
PyObject *awaitable = anextawaitable_getiter(obj);
|
PyObject *awaitable = anextawaitable_getiter(obj);
|
||||||
if (awaitable == NULL) {
|
if (awaitable == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
// 'arg' may be a tuple (if coming from a METH_VARARGS method)
|
||||||
|
// or a single object (if coming from a METH_O method).
|
||||||
PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg);
|
PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg);
|
||||||
Py_DECREF(awaitable);
|
Py_DECREF(awaitable);
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
|
|
@ -427,20 +435,26 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
anextawaitable_send(anextawaitableobject *obj, PyObject *arg) {
|
anextawaitable_send(PyObject *op, PyObject *arg)
|
||||||
|
{
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
return anextawaitable_proxy(obj, "send", arg);
|
return anextawaitable_proxy(obj, "send", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) {
|
anextawaitable_throw(PyObject *op, PyObject *args)
|
||||||
return anextawaitable_proxy(obj, "throw", arg);
|
{
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
|
return anextawaitable_proxy(obj, "throw", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
anextawaitable_close(anextawaitableobject *obj, PyObject *arg) {
|
anextawaitable_close(PyObject *op, PyObject *args)
|
||||||
return anextawaitable_proxy(obj, "close", arg);
|
{
|
||||||
|
anextawaitableobject *obj = anextawaitableobject_CAST(op);
|
||||||
|
return anextawaitable_proxy(obj, "close", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -464,9 +478,9 @@ PyDoc_STRVAR(close_doc,
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef anextawaitable_methods[] = {
|
static PyMethodDef anextawaitable_methods[] = {
|
||||||
{"send",(PyCFunction)anextawaitable_send, METH_O, send_doc},
|
{"send", anextawaitable_send, METH_O, send_doc},
|
||||||
{"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc},
|
{"throw", anextawaitable_throw, METH_VARARGS, throw_doc},
|
||||||
{"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc},
|
{"close", anextawaitable_close, METH_VARARGS, close_doc},
|
||||||
{NULL, NULL} /* Sentinel */
|
{NULL, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -484,7 +498,7 @@ PyTypeObject _PyAnextAwaitable_Type = {
|
||||||
sizeof(anextawaitableobject), /* tp_basicsize */
|
sizeof(anextawaitableobject), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)anextawaitable_dealloc, /* tp_dealloc */
|
anextawaitable_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_vectorcall_offset */
|
0, /* tp_vectorcall_offset */
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
|
|
@ -501,12 +515,12 @@ PyTypeObject _PyAnextAwaitable_Type = {
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||||
0, /* tp_doc */
|
0, /* tp_doc */
|
||||||
(traverseproc)anextawaitable_traverse, /* tp_traverse */
|
anextawaitable_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 */
|
||||||
(unaryfunc)anextawaitable_iternext, /* tp_iternext */
|
anextawaitable_iternext, /* tp_iternext */
|
||||||
anextawaitable_methods, /* tp_methods */
|
anextawaitable_methods, /* tp_methods */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue