Skip to content

Commit f7ee5c2

Browse files
committed
fix UBSan failures for anextawaitableobject
1 parent 49234c0 commit f7ee5c2

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

Objects/iterobject.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -312,18 +312,22 @@ typedef struct {
312312
PyObject *default_value;
313313
} anextawaitableobject;
314314

315+
#define anextawaitableobject_CAST(op) ((anextawaitableobject *)(op))
316+
315317
static void
316-
anextawaitable_dealloc(anextawaitableobject *obj)
318+
anextawaitable_dealloc(PyObject *op)
317319
{
320+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
318321
_PyObject_GC_UNTRACK(obj);
319322
Py_XDECREF(obj->wrapped);
320323
Py_XDECREF(obj->default_value);
321324
PyObject_GC_Del(obj);
322325
}
323326

324327
static int
325-
anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg)
328+
anextawaitable_traverse(PyObject *op, visitproc visit, void *arg)
326329
{
330+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
327331
Py_VISIT(obj->wrapped);
328332
Py_VISIT(obj->default_value);
329333
return 0;
@@ -360,7 +364,7 @@ anextawaitable_getiter(anextawaitableobject *obj)
360364
}
361365

362366
static PyObject *
363-
anextawaitable_iternext(anextawaitableobject *obj)
367+
anextawaitable_iternext(PyObject *op)
364368
{
365369
/* Consider the following class:
366370
*
@@ -382,6 +386,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
382386
* Then `await anext(gen)` can just call
383387
* gen.__anext__().__next__()
384388
*/
389+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
385390
PyObject *awaitable = anextawaitable_getiter(obj);
386391
if (awaitable == NULL) {
387392
return NULL;
@@ -400,11 +405,14 @@ anextawaitable_iternext(anextawaitableobject *obj)
400405

401406

402407
static PyObject *
403-
anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
408+
anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg)
409+
{
404410
PyObject *awaitable = anextawaitable_getiter(obj);
405411
if (awaitable == NULL) {
406412
return NULL;
407413
}
414+
// 'arg' may be a tuple (if coming from a METH_VARARGS method)
415+
// or a single object (if coming from a METH_O method).
408416
PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg);
409417
Py_DECREF(awaitable);
410418
if (ret != NULL) {
@@ -424,20 +432,27 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
424432

425433

426434
static PyObject *
427-
anextawaitable_send(anextawaitableobject *obj, PyObject *arg) {
435+
anextawaitable_send(PyObject *op, PyObject *arg)
436+
{
437+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
428438
return anextawaitable_proxy(obj, "send", arg);
429439
}
430440

431441

432442
static PyObject *
433-
anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) {
434-
return anextawaitable_proxy(obj, "throw", arg);
443+
anextawaitable_throw(PyObject *op, PyObject *args)
444+
{
445+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
446+
return anextawaitable_proxy(obj, "throw", args);
435447
}
436448

437449

438450
static PyObject *
439-
anextawaitable_close(anextawaitableobject *obj, PyObject *arg) {
440-
return anextawaitable_proxy(obj, "close", arg);
451+
anextawaitable_close(PyObject *op, PyObject *args)
452+
{
453+
// TODO(picnixz): what happens if we pass an argument to close()?
454+
anextawaitableobject *obj = anextawaitableobject_CAST(op);
455+
return anextawaitable_proxy(obj, "close", args);
441456
}
442457

443458

@@ -461,9 +476,9 @@ PyDoc_STRVAR(close_doc,
461476

462477

463478
static PyMethodDef anextawaitable_methods[] = {
464-
{"send",(PyCFunction)anextawaitable_send, METH_O, send_doc},
465-
{"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc},
466-
{"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc},
479+
{"send", anextawaitable_send, METH_O, send_doc},
480+
{"throw", anextawaitable_throw, METH_VARARGS, throw_doc},
481+
{"close", anextawaitable_close, METH_VARARGS, close_doc},
467482
{NULL, NULL} /* Sentinel */
468483
};
469484

@@ -481,7 +496,7 @@ PyTypeObject _PyAnextAwaitable_Type = {
481496
sizeof(anextawaitableobject), /* tp_basicsize */
482497
0, /* tp_itemsize */
483498
/* methods */
484-
(destructor)anextawaitable_dealloc, /* tp_dealloc */
499+
anextawaitable_dealloc, /* tp_dealloc */
485500
0, /* tp_vectorcall_offset */
486501
0, /* tp_getattr */
487502
0, /* tp_setattr */
@@ -498,12 +513,12 @@ PyTypeObject _PyAnextAwaitable_Type = {
498513
0, /* tp_as_buffer */
499514
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
500515
0, /* tp_doc */
501-
(traverseproc)anextawaitable_traverse, /* tp_traverse */
516+
anextawaitable_traverse, /* tp_traverse */
502517
0, /* tp_clear */
503518
0, /* tp_richcompare */
504519
0, /* tp_weaklistoffset */
505520
PyObject_SelfIter, /* tp_iter */
506-
(unaryfunc)anextawaitable_iternext, /* tp_iternext */
521+
anextawaitable_iternext, /* tp_iternext */
507522
anextawaitable_methods, /* tp_methods */
508523
};
509524

0 commit comments

Comments
 (0)