Skip to content

Commit 1988003

Browse files
authored
gh-111178: fix UBSan failures in Modules/_io/*.c (GH-129083)
* fix UBSan failures for `buffered`, `rwpair`, `bytesio`, `bytesiobuf`, `iobase`, `stringio`, `nldecoder_object`, `textio`, `winconsoleio` * arg names: use 'dummy' for NOARGS method and 'args' for others
1 parent 421ea12 commit 1988003

File tree

7 files changed

+230
-163
lines changed

7 files changed

+230
-163
lines changed

Modules/_io/bufferedio.c

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ typedef struct {
261261
PyObject *weakreflist;
262262
} buffered;
263263

264+
#define buffered_CAST(op) ((buffered *)(op))
265+
264266
/*
265267
Implementation notes:
266268
@@ -399,25 +401,27 @@ _enter_buffered_busy(buffered *self)
399401

400402

401403
static int
402-
buffered_clear(buffered *self)
404+
buffered_clear(PyObject *op)
403405
{
406+
buffered *self = buffered_CAST(op);
404407
self->ok = 0;
405408
Py_CLEAR(self->raw);
406409
Py_CLEAR(self->dict);
407410
return 0;
408411
}
409412

410413
static void
411-
buffered_dealloc(buffered *self)
414+
buffered_dealloc(PyObject *op)
412415
{
416+
buffered *self = buffered_CAST(op);
413417
PyTypeObject *tp = Py_TYPE(self);
414418
self->finalizing = 1;
415-
if (_PyIOBase_finalize((PyObject *) self) < 0)
419+
if (_PyIOBase_finalize(op) < 0)
416420
return;
417421
_PyObject_GC_UNTRACK(self);
418422
self->ok = 0;
419423
if (self->weakreflist != NULL)
420-
PyObject_ClearWeakRefs((PyObject *)self);
424+
PyObject_ClearWeakRefs(op);
421425
if (self->buffer) {
422426
PyMem_Free(self->buffer);
423427
self->buffer = NULL;
@@ -426,8 +430,8 @@ buffered_dealloc(buffered *self)
426430
PyThread_free_lock(self->lock);
427431
self->lock = NULL;
428432
}
429-
(void)buffered_clear(self);
430-
tp->tp_free((PyObject *)self);
433+
(void)buffered_clear(op);
434+
tp->tp_free(self);
431435
Py_DECREF(tp);
432436
}
433437

@@ -2227,6 +2231,8 @@ typedef struct {
22272231
PyObject *weakreflist;
22282232
} rwpair;
22292233

2234+
#define rwpair_CAST(op) ((rwpair *)(op))
2235+
22302236
/*[clinic input]
22312237
_io.BufferedRWPair.__init__
22322238
reader: object
@@ -2276,8 +2282,9 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
22762282
}
22772283

22782284
static int
2279-
bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2285+
bufferedrwpair_traverse(PyObject *op, visitproc visit, void *arg)
22802286
{
2287+
rwpair *self = rwpair_CAST(op);
22812288
Py_VISIT(Py_TYPE(self));
22822289
Py_VISIT(self->dict);
22832290
Py_VISIT(self->reader);
@@ -2286,23 +2293,25 @@ bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
22862293
}
22872294

22882295
static int
2289-
bufferedrwpair_clear(rwpair *self)
2296+
bufferedrwpair_clear(PyObject *op)
22902297
{
2298+
rwpair *self = rwpair_CAST(op);
22912299
Py_CLEAR(self->reader);
22922300
Py_CLEAR(self->writer);
22932301
Py_CLEAR(self->dict);
22942302
return 0;
22952303
}
22962304

22972305
static void
2298-
bufferedrwpair_dealloc(rwpair *self)
2306+
bufferedrwpair_dealloc(PyObject *op)
22992307
{
2308+
rwpair *self = rwpair_CAST(op);
23002309
PyTypeObject *tp = Py_TYPE(self);
23012310
_PyObject_GC_UNTRACK(self);
23022311
if (self->weakreflist != NULL)
2303-
PyObject_ClearWeakRefs((PyObject *)self);
2304-
(void)bufferedrwpair_clear(self);
2305-
tp->tp_free((PyObject *) self);
2312+
PyObject_ClearWeakRefs(op);
2313+
(void)bufferedrwpair_clear(op);
2314+
tp->tp_free(self);
23062315
Py_DECREF(tp);
23072316
}
23082317

@@ -2328,62 +2337,72 @@ _forward_call(buffered *self, PyObject *name, PyObject *args)
23282337
}
23292338

23302339
static PyObject *
2331-
bufferedrwpair_read(rwpair *self, PyObject *args)
2340+
bufferedrwpair_read(PyObject *op, PyObject *args)
23322341
{
2342+
rwpair *self = rwpair_CAST(op);
23332343
return _forward_call(self->reader, &_Py_ID(read), args);
23342344
}
23352345

23362346
static PyObject *
2337-
bufferedrwpair_peek(rwpair *self, PyObject *args)
2347+
bufferedrwpair_peek(PyObject *op, PyObject *args)
23382348
{
2349+
rwpair *self = rwpair_CAST(op);
23392350
return _forward_call(self->reader, &_Py_ID(peek), args);
23402351
}
23412352

23422353
static PyObject *
2343-
bufferedrwpair_read1(rwpair *self, PyObject *args)
2354+
bufferedrwpair_read1(PyObject *op, PyObject *args)
23442355
{
2356+
rwpair *self = rwpair_CAST(op);
23452357
return _forward_call(self->reader, &_Py_ID(read1), args);
23462358
}
23472359

23482360
static PyObject *
2349-
bufferedrwpair_readinto(rwpair *self, PyObject *args)
2361+
bufferedrwpair_readinto(PyObject *op, PyObject *args)
23502362
{
2363+
rwpair *self = rwpair_CAST(op);
23512364
return _forward_call(self->reader, &_Py_ID(readinto), args);
23522365
}
23532366

23542367
static PyObject *
2355-
bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2368+
bufferedrwpair_readinto1(PyObject *op, PyObject *args)
23562369
{
2370+
rwpair *self = rwpair_CAST(op);
23572371
return _forward_call(self->reader, &_Py_ID(readinto1), args);
23582372
}
23592373

23602374
static PyObject *
2361-
bufferedrwpair_write(rwpair *self, PyObject *args)
2375+
bufferedrwpair_write(PyObject *op, PyObject *args)
23622376
{
2377+
rwpair *self = rwpair_CAST(op);
23632378
return _forward_call(self->writer, &_Py_ID(write), args);
23642379
}
23652380

23662381
static PyObject *
2367-
bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
2382+
bufferedrwpair_flush(PyObject *op, PyObject *Py_UNUSED(dummy))
23682383
{
2384+
rwpair *self = rwpair_CAST(op);
23692385
return _forward_call(self->writer, &_Py_ID(flush), NULL);
23702386
}
23712387

23722388
static PyObject *
2373-
bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
2389+
bufferedrwpair_readable(PyObject *op, PyObject *Py_UNUSED(dummy))
23742390
{
2391+
rwpair *self = rwpair_CAST(op);
23752392
return _forward_call(self->reader, &_Py_ID(readable), NULL);
23762393
}
23772394

23782395
static PyObject *
2379-
bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
2396+
bufferedrwpair_writable(PyObject *op, PyObject *Py_UNUSED(dummy))
23802397
{
2398+
rwpair *self = rwpair_CAST(op);
23812399
return _forward_call(self->writer, &_Py_ID(writable), NULL);
23822400
}
23832401

23842402
static PyObject *
2385-
bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
2403+
bufferedrwpair_close(PyObject *op, PyObject *Py_UNUSED(dummy))
23862404
{
2405+
rwpair *self = rwpair_CAST(op);
23872406
PyObject *exc = NULL;
23882407
PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL);
23892408
if (ret == NULL) {
@@ -2401,8 +2420,9 @@ bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
24012420
}
24022421

24032422
static PyObject *
2404-
bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
2423+
bufferedrwpair_isatty(PyObject *op, PyObject *Py_UNUSED(dummy))
24052424
{
2425+
rwpair *self = rwpair_CAST(op);
24062426
PyObject *ret = _forward_call(self->writer, &_Py_ID(isatty), NULL);
24072427

24082428
if (ret != Py_False) {
@@ -2415,8 +2435,9 @@ bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
24152435
}
24162436

24172437
static PyObject *
2418-
bufferedrwpair_closed_get(rwpair *self, void *context)
2438+
bufferedrwpair_closed_get(PyObject *op, void *Py_UNUSED(dummy))
24192439
{
2440+
rwpair *self = rwpair_CAST(op);
24202441
if (self->writer == NULL) {
24212442
PyErr_SetString(PyExc_RuntimeError,
24222443
"the BufferedRWPair object is being garbage-collected");
@@ -2633,20 +2654,20 @@ PyType_Spec bufferedwriter_spec = {
26332654
};
26342655

26352656
static PyMethodDef bufferedrwpair_methods[] = {
2636-
{"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2637-
{"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2638-
{"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2639-
{"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
2640-
{"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
2657+
{"read", bufferedrwpair_read, METH_VARARGS},
2658+
{"peek", bufferedrwpair_peek, METH_VARARGS},
2659+
{"read1", bufferedrwpair_read1, METH_VARARGS},
2660+
{"readinto", bufferedrwpair_readinto, METH_VARARGS},
2661+
{"readinto1", bufferedrwpair_readinto1, METH_VARARGS},
26412662

2642-
{"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2643-
{"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2663+
{"write", bufferedrwpair_write, METH_VARARGS},
2664+
{"flush", bufferedrwpair_flush, METH_NOARGS},
26442665

2645-
{"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2646-
{"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2666+
{"readable", bufferedrwpair_readable, METH_NOARGS},
2667+
{"writable", bufferedrwpair_writable, METH_NOARGS},
26472668

2648-
{"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2649-
{"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2669+
{"close", bufferedrwpair_close, METH_NOARGS},
2670+
{"isatty", bufferedrwpair_isatty, METH_NOARGS},
26502671

26512672
{NULL, NULL}
26522673
};
@@ -2658,7 +2679,7 @@ static PyMemberDef bufferedrwpair_members[] = {
26582679
};
26592680

26602681
static PyGetSetDef bufferedrwpair_getset[] = {
2661-
{"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2682+
{"closed", bufferedrwpair_closed_get, NULL, NULL},
26622683
{NULL}
26632684
};
26642685

0 commit comments

Comments
 (0)