]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111178: fix UBSan failures in `Modules/_io/*.c` (GH-129083)
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Sat, 8 Feb 2025 13:21:32 +0000 (14:21 +0100)
committerGitHub <noreply@github.com>
Sat, 8 Feb 2025 13:21:32 +0000 (14:21 +0100)
* 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

Modules/_io/bufferedio.c
Modules/_io/bytesio.c
Modules/_io/fileio.c
Modules/_io/iobase.c
Modules/_io/stringio.c
Modules/_io/textio.c
Modules/_io/winconsoleio.c

index bc5fff54a62b6dac3abfd54797839a3764c12f57..53c4702f673786ca9e5aa8753bedd69555f876f0 100644 (file)
@@ -261,6 +261,8 @@ typedef struct {
     PyObject *weakreflist;
 } buffered;
 
+#define buffered_CAST(op)   ((buffered *)(op))
+
 /*
     Implementation notes:
 
@@ -399,8 +401,9 @@ _enter_buffered_busy(buffered *self)
 
 
 static int
-buffered_clear(buffered *self)
+buffered_clear(PyObject *op)
 {
+    buffered *self = buffered_CAST(op);
     self->ok = 0;
     Py_CLEAR(self->raw);
     Py_CLEAR(self->dict);
@@ -408,16 +411,17 @@ buffered_clear(buffered *self)
 }
 
 static void
-buffered_dealloc(buffered *self)
+buffered_dealloc(PyObject *op)
 {
+    buffered *self = buffered_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     self->finalizing = 1;
-    if (_PyIOBase_finalize((PyObject *) self) < 0)
+    if (_PyIOBase_finalize(op) < 0)
         return;
     _PyObject_GC_UNTRACK(self);
     self->ok = 0;
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *)self);
+        PyObject_ClearWeakRefs(op);
     if (self->buffer) {
         PyMem_Free(self->buffer);
         self->buffer = NULL;
@@ -426,8 +430,8 @@ buffered_dealloc(buffered *self)
         PyThread_free_lock(self->lock);
         self->lock = NULL;
     }
-    (void)buffered_clear(self);
-    tp->tp_free((PyObject *)self);
+    (void)buffered_clear(op);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -2227,6 +2231,8 @@ typedef struct {
     PyObject *weakreflist;
 } rwpair;
 
+#define rwpair_CAST(op) ((rwpair *)(op))
+
 /*[clinic input]
 _io.BufferedRWPair.__init__
     reader: object
@@ -2276,8 +2282,9 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
 }
 
 static int
-bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
+bufferedrwpair_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    rwpair *self = rwpair_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->dict);
     Py_VISIT(self->reader);
@@ -2286,8 +2293,9 @@ bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
 }
 
 static int
-bufferedrwpair_clear(rwpair *self)
+bufferedrwpair_clear(PyObject *op)
 {
+    rwpair *self = rwpair_CAST(op);
     Py_CLEAR(self->reader);
     Py_CLEAR(self->writer);
     Py_CLEAR(self->dict);
@@ -2295,14 +2303,15 @@ bufferedrwpair_clear(rwpair *self)
 }
 
 static void
-bufferedrwpair_dealloc(rwpair *self)
+bufferedrwpair_dealloc(PyObject *op)
 {
+    rwpair *self = rwpair_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     _PyObject_GC_UNTRACK(self);
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *)self);
-    (void)bufferedrwpair_clear(self);
-    tp->tp_free((PyObject *) self);
+        PyObject_ClearWeakRefs(op);
+    (void)bufferedrwpair_clear(op);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -2328,62 +2337,72 @@ _forward_call(buffered *self, PyObject *name, PyObject *args)
 }
 
 static PyObject *
-bufferedrwpair_read(rwpair *self, PyObject *args)
+bufferedrwpair_read(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(read), args);
 }
 
 static PyObject *
-bufferedrwpair_peek(rwpair *self, PyObject *args)
+bufferedrwpair_peek(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(peek), args);
 }
 
 static PyObject *
-bufferedrwpair_read1(rwpair *self, PyObject *args)
+bufferedrwpair_read1(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(read1), args);
 }
 
 static PyObject *
-bufferedrwpair_readinto(rwpair *self, PyObject *args)
+bufferedrwpair_readinto(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(readinto), args);
 }
 
 static PyObject *
-bufferedrwpair_readinto1(rwpair *self, PyObject *args)
+bufferedrwpair_readinto1(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(readinto1), args);
 }
 
 static PyObject *
-bufferedrwpair_write(rwpair *self, PyObject *args)
+bufferedrwpair_write(PyObject *op, PyObject *args)
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->writer, &_Py_ID(write), args);
 }
 
 static PyObject *
-bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
+bufferedrwpair_flush(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->writer, &_Py_ID(flush), NULL);
 }
 
 static PyObject *
-bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
+bufferedrwpair_readable(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->reader, &_Py_ID(readable), NULL);
 }
 
 static PyObject *
-bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
+bufferedrwpair_writable(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     return _forward_call(self->writer, &_Py_ID(writable), NULL);
 }
 
 static PyObject *
-bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
+bufferedrwpair_close(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     PyObject *exc = NULL;
     PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL);
     if (ret == NULL) {
@@ -2401,8 +2420,9 @@ bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
 }
 
 static PyObject *
-bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
+bufferedrwpair_isatty(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     PyObject *ret = _forward_call(self->writer, &_Py_ID(isatty), NULL);
 
     if (ret != Py_False) {
@@ -2415,8 +2435,9 @@ bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
 }
 
 static PyObject *
-bufferedrwpair_closed_get(rwpair *self, void *context)
+bufferedrwpair_closed_get(PyObject *op, void *Py_UNUSED(dummy))
 {
+    rwpair *self = rwpair_CAST(op);
     if (self->writer == NULL) {
         PyErr_SetString(PyExc_RuntimeError,
                 "the BufferedRWPair object is being garbage-collected");
@@ -2633,20 +2654,20 @@ PyType_Spec bufferedwriter_spec = {
 };
 
 static PyMethodDef bufferedrwpair_methods[] = {
-    {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
-    {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
-    {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
-    {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
-    {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
+    {"read", bufferedrwpair_read, METH_VARARGS},
+    {"peek", bufferedrwpair_peek, METH_VARARGS},
+    {"read1", bufferedrwpair_read1, METH_VARARGS},
+    {"readinto", bufferedrwpair_readinto, METH_VARARGS},
+    {"readinto1", bufferedrwpair_readinto1, METH_VARARGS},
 
-    {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
-    {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
+    {"write", bufferedrwpair_write, METH_VARARGS},
+    {"flush", bufferedrwpair_flush, METH_NOARGS},
 
-    {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
-    {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
+    {"readable", bufferedrwpair_readable, METH_NOARGS},
+    {"writable", bufferedrwpair_writable, METH_NOARGS},
 
-    {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
-    {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
+    {"close", bufferedrwpair_close, METH_NOARGS},
+    {"isatty", bufferedrwpair_isatty, METH_NOARGS},
 
     {NULL, NULL}
 };
@@ -2658,7 +2679,7 @@ static PyMemberDef bufferedrwpair_members[] = {
 };
 
 static PyGetSetDef bufferedrwpair_getset[] = {
-    {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
+    {"closed", bufferedrwpair_closed_get, NULL, NULL},
     {NULL}
 };
 
index 16095333db66382cefbdf491d04db8a3cc089a70..dc4e40b9f09a1df8824f4d78fa7bb2cbcc40a595 100644 (file)
@@ -21,11 +21,15 @@ typedef struct {
     Py_ssize_t exports;
 } bytesio;
 
+#define bytesio_CAST(op)    ((bytesio *)(op))
+
 typedef struct {
     PyObject_HEAD
     bytesio *source;
 } bytesiobuf;
 
+#define bytesiobuf_CAST(op) ((bytesiobuf *)(op))
+
 /* The bytesio object can be in three states:
   * Py_REFCNT(buf) == 1, exports == 0.
   * Py_REFCNT(buf) > 1.  exports == 0,
@@ -239,8 +243,9 @@ write_bytes(bytesio *self, PyObject *b)
 }
 
 static PyObject *
-bytesio_get_closed(bytesio *self, void *Py_UNUSED(ignored))
+bytesio_get_closed(PyObject *op, void *Py_UNUSED(closure))
 {
+    bytesio *self = bytesio_CAST(op);
     if (self->buf == NULL) {
         Py_RETURN_TRUE;
     }
@@ -620,9 +625,10 @@ _io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
 }
 
 static PyObject *
-bytesio_iternext(bytesio *self)
+bytesio_iternext(PyObject *op)
 {
     Py_ssize_t n;
+    bytesio *self = bytesio_CAST(op);
 
     CHECK_CLOSED(self);
 
@@ -783,8 +789,9 @@ _io_BytesIO_close_impl(bytesio *self)
  */
 
 static PyObject *
-bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored))
+bytesio_getstate(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    bytesio *self = bytesio_CAST(op);
     PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
     PyObject *dict;
     PyObject *state;
@@ -808,12 +815,13 @@ bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored))
 }
 
 static PyObject *
-bytesio_setstate(bytesio *self, PyObject *state)
+bytesio_setstate(PyObject *op, PyObject *state)
 {
     PyObject *result;
     PyObject *position_obj;
     PyObject *dict;
     Py_ssize_t pos;
+    bytesio *self = bytesio_CAST(op);
 
     assert(state != NULL);
 
@@ -883,8 +891,9 @@ bytesio_setstate(bytesio *self, PyObject *state)
 }
 
 static void
-bytesio_dealloc(bytesio *self)
+bytesio_dealloc(PyObject *op)
 {
+    bytesio *self = bytesio_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     _PyObject_GC_UNTRACK(self);
     if (self->exports > 0) {
@@ -895,7 +904,7 @@ bytesio_dealloc(bytesio *self)
     Py_CLEAR(self->buf);
     Py_CLEAR(self->dict);
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *) self);
+        PyObject_ClearWeakRefs(op);
     tp->tp_free(self);
     Py_DECREF(tp);
 }
@@ -961,8 +970,9 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
 }
 
 static PyObject *
-bytesio_sizeof(bytesio *self, void *unused)
+bytesio_sizeof(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
+    bytesio *self = bytesio_CAST(op);
     size_t res = _PyObject_SIZE(Py_TYPE(self));
     if (self->buf && !SHARED_BUF(self)) {
         size_t s = _PySys_GetSizeOf(self->buf);
@@ -975,8 +985,9 @@ bytesio_sizeof(bytesio *self, void *unused)
 }
 
 static int
-bytesio_traverse(bytesio *self, visitproc visit, void *arg)
+bytesio_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    bytesio *self = bytesio_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->dict);
     Py_VISIT(self->buf);
@@ -984,8 +995,9 @@ bytesio_traverse(bytesio *self, visitproc visit, void *arg)
 }
 
 static int
-bytesio_clear(bytesio *self)
+bytesio_clear(PyObject *op)
 {
+    bytesio *self = bytesio_CAST(op);
     Py_CLEAR(self->dict);
     if (self->exports == 0) {
         Py_CLEAR(self->buf);
@@ -999,7 +1011,7 @@ bytesio_clear(bytesio *self)
 #undef clinic_state
 
 static PyGetSetDef bytesio_getsetlist[] = {
-    {"closed",  (getter)bytesio_get_closed, NULL,
+    {"closed",  bytesio_get_closed, NULL,
      "True if the file is closed."},
     {NULL},            /* sentinel */
 };
@@ -1023,9 +1035,9 @@ static struct PyMethodDef bytesio_methods[] = {
     _IO_BYTESIO_GETVALUE_METHODDEF
     _IO_BYTESIO_SEEK_METHODDEF
     _IO_BYTESIO_TRUNCATE_METHODDEF
-    {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
-    {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
-    {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
+    {"__getstate__",  bytesio_getstate,  METH_NOARGS, NULL},
+    {"__setstate__",  bytesio_setstate,  METH_O, NULL},
+    {"__sizeof__", bytesio_sizeof,     METH_NOARGS, NULL},
     {NULL, NULL}        /* sentinel */
 };
 
@@ -1065,9 +1077,10 @@ PyType_Spec bytesio_spec = {
  */
 
 static int
-bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
+bytesiobuf_getbuffer(PyObject *op, Py_buffer *view, int flags)
 {
-    bytesio *b = (bytesio *) obj->source;
+    bytesiobuf *obj = bytesiobuf_CAST(op);
+    bytesio *b = bytesio_CAST(obj->source);
 
     if (view == NULL) {
         PyErr_SetString(PyExc_BufferError,
@@ -1080,7 +1093,7 @@ bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
     }
 
     /* cannot fail if view != NULL and readonly == 0 */
-    (void)PyBuffer_FillInfo(view, (PyObject*)obj,
+    (void)PyBuffer_FillInfo(view, op,
                             PyBytes_AS_STRING(b->buf), b->string_size,
                             0, flags);
     b->exports++;
@@ -1088,26 +1101,29 @@ bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
 }
 
 static void
-bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
+bytesiobuf_releasebuffer(PyObject *op, Py_buffer *Py_UNUSED(view))
 {
-    bytesio *b = (bytesio *) obj->source;
+    bytesiobuf *obj = bytesiobuf_CAST(op);
+    bytesio *b = bytesio_CAST(obj->source);
     b->exports--;
 }
 
 static int
-bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
+bytesiobuf_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    bytesiobuf *self = bytesiobuf_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->source);
     return 0;
 }
 
 static void
-bytesiobuf_dealloc(bytesiobuf *self)
+bytesiobuf_dealloc(PyObject *op)
 {
+    bytesiobuf *self = bytesiobuf_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     /* bpo-31095: UnTrack is needed before calling any callbacks */
-    PyObject_GC_UnTrack(self);
+    PyObject_GC_UnTrack(op);
     Py_CLEAR(self->source);
     tp->tp_free(self);
     Py_DECREF(tp);
index f27f2ed484327172711e2e3883b2ef9162f68047..89f1cfe6b2093507ae4304dd02179068e1f8241b 100644 (file)
@@ -83,7 +83,7 @@ typedef struct {
 } fileio;
 
 #define PyFileIO_Check(state, op) (PyObject_TypeCheck((op), state->PyFileIO_Type))
-#define _PyFileIO_CAST(op) _Py_CAST(fileio*, (op))
+#define PyFileIO_CAST(op) ((fileio *)(op))
 
 /* Forward declarations */
 static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error);
@@ -91,7 +91,7 @@ static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool
 int
 _PyFileIO_closed(PyObject *self)
 {
-    return (_PyFileIO_CAST(self)->fd < 0);
+    return (PyFileIO_CAST(self)->fd < 0);
 }
 
 /* Because this can call arbitrary code, it shouldn't be called when
@@ -100,7 +100,7 @@ _PyFileIO_closed(PyObject *self)
 static PyObject *
 fileio_dealloc_warn(PyObject *op, PyObject *source)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     if (self->fd >= 0 && self->closefd) {
         PyObject *exc = PyErr_GetRaisedException();
         if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
@@ -542,7 +542,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
 static int
 fileio_traverse(PyObject *op, visitproc visit, void *arg)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->dict);
     return 0;
@@ -551,7 +551,7 @@ fileio_traverse(PyObject *op, visitproc visit, void *arg)
 static int
 fileio_clear(PyObject *op)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     Py_CLEAR(self->dict);
     return 0;
 }
@@ -559,7 +559,7 @@ fileio_clear(PyObject *op)
 static void
 fileio_dealloc(PyObject *op)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     self->finalizing = 1;
     if (_PyIOBase_finalize(op) < 0) {
         return;
@@ -1161,7 +1161,7 @@ mode_string(fileio *self)
 static PyObject *
 fileio_repr(PyObject *op)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     const char *type_name = Py_TYPE(self)->tp_name;
 
     if (self->fd < 0) {
@@ -1227,9 +1227,9 @@ _io_FileIO_isatty_impl(fileio *self)
    context TOCTOU issues (the fd could be arbitrarily modified by
    surrounding code). */
 static PyObject *
-_io_FileIO_isatty_open_only(PyObject *op, PyObject *Py_UNUSED(ignored))
+_io_FileIO_isatty_open_only(PyObject *op, PyObject *Py_UNUSED(dummy))
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     if (self->stat_atopen != NULL && !S_ISCHR(self->stat_atopen->st_mode)) {
         Py_RETURN_FALSE;
     }
@@ -1264,28 +1264,28 @@ static PyMethodDef fileio_methods[] = {
 static PyObject *
 fileio_get_closed(PyObject *op, void *closure)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     return PyBool_FromLong((long)(self->fd < 0));
 }
 
 static PyObject *
 fileio_get_closefd(PyObject *op, void *closure)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     return PyBool_FromLong((long)(self->closefd));
 }
 
 static PyObject *
 fileio_get_mode(PyObject *op, void *closure)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
     return PyUnicode_FromString(mode_string(self));
 }
 
 static PyObject *
 fileio_get_blksize(PyObject *op, void *closure)
 {
-    fileio *self = _PyFileIO_CAST(op);
+    fileio *self = PyFileIO_CAST(op);
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
     if (self->stat_atopen != NULL && self->stat_atopen->st_blksize > 1) {
         return PyLong_FromLong(self->stat_atopen->st_blksize);
index f87043df12689527b11cff8b6beb5082d99f12cf..7e0822e3350eebe87ad8bf10439b60684f07f29c 100644 (file)
@@ -35,6 +35,8 @@ typedef struct {
     PyObject *weakreflist;
 } iobase;
 
+#define iobase_CAST(op) ((iobase *)(op))
+
 PyDoc_STRVAR(iobase_doc,
     "The abstract base class for all I/O classes.\n"
     "\n"
@@ -343,16 +345,18 @@ _PyIOBase_finalize(PyObject *self)
 }
 
 static int
-iobase_traverse(iobase *self, visitproc visit, void *arg)
+iobase_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    iobase *self = iobase_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->dict);
     return 0;
 }
 
 static int
-iobase_clear(iobase *self)
+iobase_clear(PyObject *op)
 {
+    iobase *self = iobase_CAST(op);
     Py_CLEAR(self->dict);
     return 0;
 }
@@ -360,14 +364,15 @@ iobase_clear(iobase *self)
 /* Destructor */
 
 static void
-iobase_dealloc(iobase *self)
+iobase_dealloc(PyObject *op)
 {
     /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
        are still available here for close() to use.
        However, if the derived class declares a __slots__, those slots are
        already gone.
     */
-    if (_PyIOBase_finalize((PyObject *) self) < 0) {
+    iobase *self = iobase_CAST(op);
+    if (_PyIOBase_finalize(op) < 0) {
         /* When called from a heap type's dealloc, the type will be
            decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
         if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) {
@@ -378,9 +383,9 @@ iobase_dealloc(iobase *self)
     PyTypeObject *tp = Py_TYPE(self);
     _PyObject_GC_UNTRACK(self);
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *) self);
+        PyObject_ClearWeakRefs(op);
     Py_CLEAR(self->dict);
-    tp->tp_free((PyObject *)self);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -853,7 +858,7 @@ static PyMethodDef iobase_methods[] = {
 
 static PyGetSetDef iobase_getset[] = {
     {"__dict__", PyObject_GenericGetDict, NULL, NULL},
-    {"closed", (getter)iobase_closed_get, NULL, NULL},
+    {"closed", iobase_closed_get, NULL, NULL},
     {NULL}
 };
 
index d1a71298a9087f5fc5ed0c2ceb9b4ec55c16b5d1..9d1bfa3ea05ceab67663680678d623a961cb7b56 100644 (file)
@@ -45,6 +45,8 @@ typedef struct {
     _PyIO_State *module_state;
 } stringio;
 
+#define stringio_CAST(op)   ((stringio *)(op))
+
 #define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
 #include "clinic/stringio.c.h"
 #undef clinic_state
@@ -402,9 +404,10 @@ _io_StringIO_readline_impl(stringio *self, Py_ssize_t size)
 }
 
 static PyObject *
-stringio_iternext(stringio *self)
+stringio_iternext(PyObject *op)
 {
     PyObject *line;
+    stringio *self = stringio_CAST(op);
 
     CHECK_INITIALIZED(self);
     CHECK_CLOSED(self);
@@ -416,8 +419,7 @@ stringio_iternext(stringio *self)
     }
     else {
         /* XXX is subclassing StringIO really supported? */
-        line = PyObject_CallMethodNoArgs((PyObject *)self,
-                                             &_Py_ID(readline));
+        line = PyObject_CallMethodNoArgs(op, &_Py_ID(readline));
         if (line && !PyUnicode_Check(line)) {
             PyErr_Format(PyExc_OSError,
                          "readline() should have returned a str object, "
@@ -591,8 +593,9 @@ _io_StringIO_close_impl(stringio *self)
 }
 
 static int
-stringio_traverse(stringio *self, visitproc visit, void *arg)
+stringio_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    stringio *self = stringio_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->readnl);
     Py_VISIT(self->writenl);
@@ -602,8 +605,9 @@ stringio_traverse(stringio *self, visitproc visit, void *arg)
 }
 
 static int
-stringio_clear(stringio *self)
+stringio_clear(PyObject *op)
 {
+    stringio *self = stringio_CAST(op);
     Py_CLEAR(self->readnl);
     Py_CLEAR(self->writenl);
     Py_CLEAR(self->decoder);
@@ -612,8 +616,9 @@ stringio_clear(stringio *self)
 }
 
 static void
-stringio_dealloc(stringio *self)
+stringio_dealloc(PyObject *op)
 {
+    stringio *self = stringio_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     _PyObject_GC_UNTRACK(self);
     self->ok = 0;
@@ -622,9 +627,9 @@ stringio_dealloc(stringio *self)
         self->buf = NULL;
     }
     PyUnicodeWriter_Discard(self->writer);
-    (void)stringio_clear(self);
+    (void)stringio_clear(op);
     if (self->weakreflist != NULL) {
-        PyObject_ClearWeakRefs((PyObject *) self);
+        PyObject_ClearWeakRefs(op);
     }
     tp->tp_free(self);
     Py_DECREF(tp);
index 791ee070401fe5831965724445c7fcfda943219c..935aaab20a031f62bb3c98e97e85c905ea16c794 100644 (file)
@@ -223,6 +223,8 @@ struct nldecoder_object {
     unsigned int seennl: 3;
 };
 
+#define nldecoder_object_CAST(op)   ((nldecoder_object *)(op))
+
 /*[clinic input]
 _io.IncrementalNewlineDecoder.__init__
     decoder: object
@@ -263,9 +265,9 @@ _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self,
 }
 
 static int
-incrementalnewlinedecoder_traverse(nldecoder_object *self, visitproc visit,
-                                   void *arg)
+incrementalnewlinedecoder_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    nldecoder_object *self = nldecoder_object_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->decoder);
     Py_VISIT(self->errors);
@@ -273,20 +275,22 @@ incrementalnewlinedecoder_traverse(nldecoder_object *self, visitproc visit,
 }
 
 static int
-incrementalnewlinedecoder_clear(nldecoder_object *self)
+incrementalnewlinedecoder_clear(PyObject *op)
 {
+    nldecoder_object *self = nldecoder_object_CAST(op);
     Py_CLEAR(self->decoder);
     Py_CLEAR(self->errors);
     return 0;
 }
 
 static void
-incrementalnewlinedecoder_dealloc(nldecoder_object *self)
+incrementalnewlinedecoder_dealloc(PyObject *op)
 {
+    nldecoder_object *self = nldecoder_object_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     _PyObject_GC_UNTRACK(self);
-    (void)incrementalnewlinedecoder_clear(self);
-    tp->tp_free((PyObject *)self);
+    (void)incrementalnewlinedecoder_clear(op);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -323,7 +327,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself,
 {
     PyObject *output;
     Py_ssize_t output_len;
-    nldecoder_object *self = (nldecoder_object *) myself;
+    nldecoder_object *self = nldecoder_object_CAST(myself);
 
     CHECK_INITIALIZED_DECODER(self);
 
@@ -625,8 +629,9 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self)
 }
 
 static PyObject *
-incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
+incrementalnewlinedecoder_newlines_get(PyObject *op, void *Py_UNUSED(context))
 {
+    nldecoder_object *self = nldecoder_object_CAST(op);
     CHECK_INITIALIZED_DECODER(self);
 
     switch (self->seennl) {
@@ -652,8 +657,7 @@ incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
 
 /* TextIOWrapper */
 
-typedef PyObject *
-        (*encodefunc_t)(PyObject *, PyObject *);
+typedef PyObject *(*encodefunc_t)(PyObject *, PyObject *);
 
 struct textio
 {
@@ -716,6 +720,8 @@ struct textio
     _PyIO_State *state;
 };
 
+#define textio_CAST(op) ((textio *)(op))
+
 static void
 textiowrapper_set_decoded_chars(textio *self, PyObject *chars);
 
@@ -723,78 +729,81 @@ textiowrapper_set_decoded_chars(textio *self, PyObject *chars);
    encoding methods for the most popular encodings. */
 
 static PyObject *
-ascii_encode(textio *self, PyObject *text)
+ascii_encode(PyObject *op, PyObject *text)
 {
+    textio *self = textio_CAST(op);
     return _PyUnicode_AsASCIIString(text, PyUnicode_AsUTF8(self->errors));
 }
 
 static PyObject *
-utf16be_encode(textio *self, PyObject *text)
+utf16be_encode(PyObject *op, PyObject *text)
 {
-    return _PyUnicode_EncodeUTF16(text,
-                                  PyUnicode_AsUTF8(self->errors), 1);
+    textio *self = textio_CAST(op);
+    return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), 1);
 }
 
 static PyObject *
-utf16le_encode(textio *self, PyObject *text)
+utf16le_encode(PyObject *op, PyObject *text)
 {
-    return _PyUnicode_EncodeUTF16(text,
-                                  PyUnicode_AsUTF8(self->errors), -1);
+    textio *self = textio_CAST(op);
+    return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), -1);
 }
 
 static PyObject *
-utf16_encode(textio *self, PyObject *text)
+utf16_encode(PyObject *op, PyObject *text)
 {
+    textio *self = textio_CAST(op);
     if (!self->encoding_start_of_stream) {
         /* Skip the BOM and use native byte ordering */
 #if PY_BIG_ENDIAN
-        return utf16be_encode(self, text);
+        return utf16be_encode(op, text);
 #else
-        return utf16le_encode(self, text);
+        return utf16le_encode(op, text);
 #endif
     }
-    return _PyUnicode_EncodeUTF16(text,
-                                  PyUnicode_AsUTF8(self->errors), 0);
+    return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), 0);
 }
 
 static PyObject *
-utf32be_encode(textio *self, PyObject *text)
+utf32be_encode(PyObject *op, PyObject *text)
 {
-    return _PyUnicode_EncodeUTF32(text,
-                                  PyUnicode_AsUTF8(self->errors), 1);
+    textio *self = textio_CAST(op);
+    return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), 1);
 }
 
 static PyObject *
-utf32le_encode(textio *self, PyObject *text)
+utf32le_encode(PyObject *op, PyObject *text)
 {
-    return _PyUnicode_EncodeUTF32(text,
-                                  PyUnicode_AsUTF8(self->errors), -1);
+    textio *self = textio_CAST(op);
+    return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), -1);
 }
 
 static PyObject *
-utf32_encode(textio *self, PyObject *text)
+utf32_encode(PyObject *op, PyObject *text)
 {
+    textio *self = textio_CAST(op);
     if (!self->encoding_start_of_stream) {
         /* Skip the BOM and use native byte ordering */
 #if PY_BIG_ENDIAN
-        return utf32be_encode(self, text);
+        return utf32be_encode(op, text);
 #else
-        return utf32le_encode(self, text);
+        return utf32le_encode(op, text);
 #endif
     }
-    return _PyUnicode_EncodeUTF32(text,
-                                  PyUnicode_AsUTF8(self->errors), 0);
+    return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), 0);
 }
 
 static PyObject *
-utf8_encode(textio *self, PyObject *text)
+utf8_encode(PyObject *op, PyObject *text)
 {
+    textio *self = textio_CAST(op);
     return _PyUnicode_AsUTF8String(text, PyUnicode_AsUTF8(self->errors));
 }
 
 static PyObject *
-latin1_encode(textio *self, PyObject *text)
+latin1_encode(PyObject *op, PyObject *text)
 {
+    textio *self = textio_CAST(op);
     return _PyUnicode_AsLatin1String(text, PyUnicode_AsUTF8(self->errors));
 }
 
@@ -802,9 +811,7 @@ latin1_encode(textio *self, PyObject *text)
 static inline int
 is_asciicompat_encoding(encodefunc_t f)
 {
-    return f == (encodefunc_t) ascii_encode
-        || f == (encodefunc_t) latin1_encode
-        || f == (encodefunc_t) utf8_encode;
+    return f == ascii_encode || f == latin1_encode || f == utf8_encode;
 }
 
 /* Map normalized encoding names onto the specialized encoding funcs */
@@ -815,15 +822,15 @@ typedef struct {
 } encodefuncentry;
 
 static const encodefuncentry encodefuncs[] = {
-    {"ascii",       (encodefunc_t) ascii_encode},
-    {"iso8859-1",   (encodefunc_t) latin1_encode},
-    {"utf-8",       (encodefunc_t) utf8_encode},
-    {"utf-16-be",   (encodefunc_t) utf16be_encode},
-    {"utf-16-le",   (encodefunc_t) utf16le_encode},
-    {"utf-16",      (encodefunc_t) utf16_encode},
-    {"utf-32-be",   (encodefunc_t) utf32be_encode},
-    {"utf-32-le",   (encodefunc_t) utf32le_encode},
-    {"utf-32",      (encodefunc_t) utf32_encode},
+    {"ascii",       ascii_encode},
+    {"iso8859-1",   latin1_encode},
+    {"utf-8",       utf8_encode},
+    {"utf-16-be",   utf16be_encode},
+    {"utf-16-le",   utf16le_encode},
+    {"utf-16",      utf16_encode},
+    {"utf-32-be",   utf32be_encode},
+    {"utf-32-le",   utf32le_encode},
+    {"utf-32",      utf32_encode},
     {NULL, NULL}
 };
 
@@ -1433,8 +1440,9 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
 }
 
 static int
-textiowrapper_clear(textio *self)
+textiowrapper_clear(PyObject *op)
 {
+    textio *self = textio_CAST(op);
     self->ok = 0;
     Py_CLEAR(self->buffer);
     Py_CLEAR(self->encoding);
@@ -1452,24 +1460,26 @@ textiowrapper_clear(textio *self)
 }
 
 static void
-textiowrapper_dealloc(textio *self)
+textiowrapper_dealloc(PyObject *op)
 {
+    textio *self = textio_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     self->finalizing = 1;
-    if (_PyIOBase_finalize((PyObject *) self) < 0)
+    if (_PyIOBase_finalize(op) < 0)
         return;
     self->ok = 0;
     _PyObject_GC_UNTRACK(self);
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *)self);
-    (void)textiowrapper_clear(self);
-    tp->tp_free((PyObject *)self);
+        PyObject_ClearWeakRefs(op);
+    (void)textiowrapper_clear(op);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
 static int
-textiowrapper_traverse(textio *self, visitproc visit, void *arg)
+textiowrapper_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    textio *self = textio_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->buffer);
     Py_VISIT(self->encoding);
@@ -2963,10 +2973,11 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
 }
 
 static PyObject *
-textiowrapper_repr(textio *self)
+textiowrapper_repr(PyObject *op)
 {
     PyObject *nameobj, *modeobj, *res, *s;
     int status;
+    textio *self = textio_CAST(op);
     const char *type_name = Py_TYPE(self)->tp_name;
 
     CHECK_INITIALIZED(self);
@@ -2975,7 +2986,7 @@ textiowrapper_repr(textio *self)
     if (res == NULL)
         return NULL;
 
-    status = Py_ReprEnter((PyObject *)self);
+    status = Py_ReprEnter(op);
     if (status != 0) {
         if (status > 0) {
             PyErr_Format(PyExc_RuntimeError,
@@ -2984,7 +2995,7 @@ textiowrapper_repr(textio *self)
         }
         goto error;
     }
-    if (PyObject_GetOptionalAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) {
+    if (PyObject_GetOptionalAttr(op, &_Py_ID(name), &nameobj) < 0) {
         if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
             goto error;
         }
@@ -3000,7 +3011,7 @@ textiowrapper_repr(textio *self)
         if (res == NULL)
             goto error;
     }
-    if (PyObject_GetOptionalAttr((PyObject *) self, &_Py_ID(mode), &modeobj) < 0) {
+    if (PyObject_GetOptionalAttr(op, &_Py_ID(mode), &modeobj) < 0) {
         goto error;
     }
     if (modeobj != NULL) {
@@ -3016,14 +3027,14 @@ textiowrapper_repr(textio *self)
                              res, self->encoding);
     Py_DECREF(res);
     if (status == 0) {
-        Py_ReprLeave((PyObject *)self);
+        Py_ReprLeave(op);
     }
     return s;
 
   error:
     Py_XDECREF(res);
     if (status == 0) {
-        Py_ReprLeave((PyObject *)self);
+        Py_ReprLeave(op);
     }
     return NULL;
 }
@@ -3163,9 +3174,10 @@ _io_TextIOWrapper_close_impl(textio *self)
 }
 
 static PyObject *
-textiowrapper_iternext(textio *self)
+textiowrapper_iternext(PyObject *op)
 {
     PyObject *line;
+    textio *self = textio_CAST(op);
 
     CHECK_ATTACHED(self);
 
@@ -3175,8 +3187,7 @@ textiowrapper_iternext(textio *self)
         line = _textiowrapper_readline(self, -1);
     }
     else {
-        line = PyObject_CallMethodNoArgs((PyObject *)self,
-                                          &_Py_ID(readline));
+        line = PyObject_CallMethodNoArgs(op, &_Py_ID(readline));
         if (line && !PyUnicode_Check(line)) {
             PyErr_Format(PyExc_OSError,
                          "readline() should have returned a str object, "
@@ -3313,7 +3324,7 @@ static PyMethodDef incrementalnewlinedecoder_methods[] = {
 };
 
 static PyGetSetDef incrementalnewlinedecoder_getset[] = {
-    {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
+    {"newlines", incrementalnewlinedecoder_newlines_get, NULL, NULL},
     {NULL}
 };
 
index 3fa0301e3379917d50ce73b44dce152d4f8307cd..27c320ed073103c106ab1f3ea6599745ec42fcb4 100644 (file)
@@ -221,6 +221,8 @@ typedef struct {
     wchar_t wbuf;
 } winconsoleio;
 
+#define winconsoleio_CAST(op)   ((winconsoleio *)(op))
+
 int
 _PyWindowsConsoleIO_closed(PyObject *self)
 {
@@ -492,32 +494,35 @@ done:
 }
 
 static int
-winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg)
+winconsoleio_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->dict);
     return 0;
 }
 
 static int
-winconsoleio_clear(winconsoleio *self)
+winconsoleio_clear(PyObject *op)
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     Py_CLEAR(self->dict);
     return 0;
 }
 
 static void
-winconsoleio_dealloc(winconsoleio *self)
+winconsoleio_dealloc(PyObject *op)
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     PyTypeObject *tp = Py_TYPE(self);
     self->finalizing = 1;
-    if (_PyIOBase_finalize((PyObject *) self) < 0)
+    if (_PyIOBase_finalize(op) < 0)
         return;
     _PyObject_GC_UNTRACK(self);
     if (self->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *) self);
+        PyObject_ClearWeakRefs(op);
     Py_CLEAR(self->dict);
-    tp->tp_free((PyObject *)self);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -1137,9 +1142,10 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, PyTypeObject *cls,
 }
 
 static PyObject *
-winconsoleio_repr(winconsoleio *self)
+winconsoleio_repr(PyObject *op)
 {
-    const char *type_name = (Py_TYPE((PyObject *)self)->tp_name);
+    winconsoleio *self = winconsoleio_CAST(op);
+    const char *type_name = Py_TYPE(self)->tp_name;
 
     if (self->fd == -1) {
         return PyUnicode_FromFormat("<%.100s [closed]>", type_name);
@@ -1197,28 +1203,31 @@ static PyMethodDef winconsoleio_methods[] = {
 /* 'closed' and 'mode' are attributes for compatibility with FileIO. */
 
 static PyObject *
-get_closed(winconsoleio *self, void *closure)
+get_closed(PyObject *op, void *Py_UNUSED(closure))
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     return PyBool_FromLong((long)(self->fd == -1));
 }
 
 static PyObject *
-get_closefd(winconsoleio *self, void *closure)
+get_closefd(PyObject *op, void *Py_UNUSED(closure))
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     return PyBool_FromLong((long)(self->closefd));
 }
 
 static PyObject *
-get_mode(winconsoleio *self, void *closure)
+get_mode(PyObject *op, void *Py_UNUSED(closure))
 {
+    winconsoleio *self = winconsoleio_CAST(op);
     return PyUnicode_FromString(self->readable ? "rb" : "wb");
 }
 
 static PyGetSetDef winconsoleio_getsetlist[] = {
-    {"closed", (getter)get_closed, NULL, "True if the file is closed"},
-    {"closefd", (getter)get_closefd, NULL,
+    {"closed", get_closed, NULL, "True if the file is closed"},
+    {"closefd", get_closefd, NULL,
         "True if the file descriptor will be closed by close()."},
-    {"mode", (getter)get_mode, NULL, "String giving the file mode"},
+    {"mode", get_mode, NULL, "String giving the file mode"},
     {NULL},
 };