Skip to content

Commit 19ed68d

Browse files
committed
fix UBSan failures for textio
1 parent 9889af8 commit 19ed68d

File tree

1 file changed

+60
-55
lines changed

1 file changed

+60
-55
lines changed

Modules/_io/textio.c

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,7 @@ incrementalnewlinedecoder_newlines_get(PyObject *op, void *Py_UNUSED(context))
656656

657657
/* TextIOWrapper */
658658

659-
typedef PyObject *
660-
(*encodefunc_t)(PyObject *, PyObject *);
659+
typedef PyObject *(*encodefunc_t)(PyObject *, PyObject *);
661660

662661
struct textio
663662
{
@@ -719,6 +718,7 @@ struct textio
719718

720719
_PyIO_State *state;
721720
};
721+
#define _textio_CAST(op) ((textio *)(op))
722722

723723
static void
724724
textiowrapper_set_decoded_chars(textio *self, PyObject *chars);
@@ -727,88 +727,89 @@ textiowrapper_set_decoded_chars(textio *self, PyObject *chars);
727727
encoding methods for the most popular encodings. */
728728

729729
static PyObject *
730-
ascii_encode(textio *self, PyObject *text)
730+
ascii_encode(PyObject *op, PyObject *text)
731731
{
732+
textio *self = _textio_CAST(op);
732733
return _PyUnicode_AsASCIIString(text, PyUnicode_AsUTF8(self->errors));
733734
}
734735

735736
static PyObject *
736-
utf16be_encode(textio *self, PyObject *text)
737+
utf16be_encode(PyObject *op, PyObject *text)
737738
{
738-
return _PyUnicode_EncodeUTF16(text,
739-
PyUnicode_AsUTF8(self->errors), 1);
739+
textio *self = _textio_CAST(op);
740+
return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), 1);
740741
}
741742

742743
static PyObject *
743-
utf16le_encode(textio *self, PyObject *text)
744+
utf16le_encode(PyObject *op, PyObject *text)
744745
{
745-
return _PyUnicode_EncodeUTF16(text,
746-
PyUnicode_AsUTF8(self->errors), -1);
746+
textio *self = _textio_CAST(op);
747+
return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), -1);
747748
}
748749

749750
static PyObject *
750-
utf16_encode(textio *self, PyObject *text)
751+
utf16_encode(PyObject *op, PyObject *text)
751752
{
753+
textio *self = _textio_CAST(op);
752754
if (!self->encoding_start_of_stream) {
753755
/* Skip the BOM and use native byte ordering */
754756
#if PY_BIG_ENDIAN
755-
return utf16be_encode(self, text);
757+
return utf16be_encode(op, text);
756758
#else
757-
return utf16le_encode(self, text);
759+
return utf16le_encode(op, text);
758760
#endif
759761
}
760-
return _PyUnicode_EncodeUTF16(text,
761-
PyUnicode_AsUTF8(self->errors), 0);
762+
return _PyUnicode_EncodeUTF16(text, PyUnicode_AsUTF8(self->errors), 0);
762763
}
763764

764765
static PyObject *
765-
utf32be_encode(textio *self, PyObject *text)
766+
utf32be_encode(PyObject *op, PyObject *text)
766767
{
767-
return _PyUnicode_EncodeUTF32(text,
768-
PyUnicode_AsUTF8(self->errors), 1);
768+
textio *self = _textio_CAST(op);
769+
return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), 1);
769770
}
770771

771772
static PyObject *
772-
utf32le_encode(textio *self, PyObject *text)
773+
utf32le_encode(PyObject *op, PyObject *text)
773774
{
774-
return _PyUnicode_EncodeUTF32(text,
775-
PyUnicode_AsUTF8(self->errors), -1);
775+
textio *self = _textio_CAST(op);
776+
return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), -1);
776777
}
777778

778779
static PyObject *
779-
utf32_encode(textio *self, PyObject *text)
780+
utf32_encode(PyObject *op, PyObject *text)
780781
{
782+
textio *self = _textio_CAST(op);
781783
if (!self->encoding_start_of_stream) {
782784
/* Skip the BOM and use native byte ordering */
783785
#if PY_BIG_ENDIAN
784-
return utf32be_encode(self, text);
786+
return utf32be_encode(op, text);
785787
#else
786-
return utf32le_encode(self, text);
788+
return utf32le_encode(op, text);
787789
#endif
788790
}
789-
return _PyUnicode_EncodeUTF32(text,
790-
PyUnicode_AsUTF8(self->errors), 0);
791+
return _PyUnicode_EncodeUTF32(text, PyUnicode_AsUTF8(self->errors), 0);
791792
}
792793

793794
static PyObject *
794-
utf8_encode(textio *self, PyObject *text)
795+
utf8_encode(PyObject *op, PyObject *text)
795796
{
797+
textio *self = _textio_CAST(op);
796798
return _PyUnicode_AsUTF8String(text, PyUnicode_AsUTF8(self->errors));
797799
}
798800

799801
static PyObject *
800-
latin1_encode(textio *self, PyObject *text)
802+
latin1_encode(PyObject *op, PyObject *text)
801803
{
804+
textio *self = _textio_CAST(op);
802805
return _PyUnicode_AsLatin1String(text, PyUnicode_AsUTF8(self->errors));
803806
}
804807

805808
// Return true when encoding can be skipped when text is ascii.
806809
static inline int
807810
is_asciicompat_encoding(encodefunc_t f)
808811
{
809-
return f == (encodefunc_t) ascii_encode
810-
|| f == (encodefunc_t) latin1_encode
811-
|| f == (encodefunc_t) utf8_encode;
812+
return f == ascii_encode || f == latin1_encode || f == utf8_encode;
812813
}
813814

814815
/* Map normalized encoding names onto the specialized encoding funcs */
@@ -819,15 +820,15 @@ typedef struct {
819820
} encodefuncentry;
820821

821822
static const encodefuncentry encodefuncs[] = {
822-
{"ascii", (encodefunc_t) ascii_encode},
823-
{"iso8859-1", (encodefunc_t) latin1_encode},
824-
{"utf-8", (encodefunc_t) utf8_encode},
825-
{"utf-16-be", (encodefunc_t) utf16be_encode},
826-
{"utf-16-le", (encodefunc_t) utf16le_encode},
827-
{"utf-16", (encodefunc_t) utf16_encode},
828-
{"utf-32-be", (encodefunc_t) utf32be_encode},
829-
{"utf-32-le", (encodefunc_t) utf32le_encode},
830-
{"utf-32", (encodefunc_t) utf32_encode},
823+
{"ascii", ascii_encode},
824+
{"iso8859-1", latin1_encode},
825+
{"utf-8", utf8_encode},
826+
{"utf-16-be", utf16be_encode},
827+
{"utf-16-le", utf16le_encode},
828+
{"utf-16", utf16_encode},
829+
{"utf-32-be", utf32be_encode},
830+
{"utf-32-le", utf32le_encode},
831+
{"utf-32", utf32_encode},
831832
{NULL, NULL}
832833
};
833834

@@ -1437,8 +1438,9 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
14371438
}
14381439

14391440
static int
1440-
textiowrapper_clear(textio *self)
1441+
textiowrapper_clear(PyObject *op)
14411442
{
1443+
textio *self = _textio_CAST(op);
14421444
self->ok = 0;
14431445
Py_CLEAR(self->buffer);
14441446
Py_CLEAR(self->encoding);
@@ -1456,24 +1458,26 @@ textiowrapper_clear(textio *self)
14561458
}
14571459

14581460
static void
1459-
textiowrapper_dealloc(textio *self)
1461+
textiowrapper_dealloc(PyObject *op)
14601462
{
1463+
textio *self = _textio_CAST(op);
14611464
PyTypeObject *tp = Py_TYPE(self);
14621465
self->finalizing = 1;
1463-
if (_PyIOBase_finalize((PyObject *) self) < 0)
1466+
if (_PyIOBase_finalize(op) < 0)
14641467
return;
14651468
self->ok = 0;
14661469
_PyObject_GC_UNTRACK(self);
14671470
if (self->weakreflist != NULL)
1468-
PyObject_ClearWeakRefs((PyObject *)self);
1469-
(void)textiowrapper_clear(self);
1470-
tp->tp_free((PyObject *)self);
1471+
PyObject_ClearWeakRefs(op);
1472+
(void)textiowrapper_clear(op);
1473+
tp->tp_free(self);
14711474
Py_DECREF(tp);
14721475
}
14731476

14741477
static int
1475-
textiowrapper_traverse(textio *self, visitproc visit, void *arg)
1478+
textiowrapper_traverse(PyObject *op, visitproc visit, void *arg)
14761479
{
1480+
textio *self = _textio_CAST(op);
14771481
Py_VISIT(Py_TYPE(self));
14781482
Py_VISIT(self->buffer);
14791483
Py_VISIT(self->encoding);
@@ -2967,10 +2971,11 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
29672971
}
29682972

29692973
static PyObject *
2970-
textiowrapper_repr(textio *self)
2974+
textiowrapper_repr(PyObject *op)
29712975
{
29722976
PyObject *nameobj, *modeobj, *res, *s;
29732977
int status;
2978+
textio *self = _textio_CAST(op);
29742979
const char *type_name = Py_TYPE(self)->tp_name;
29752980

29762981
CHECK_INITIALIZED(self);
@@ -2979,7 +2984,7 @@ textiowrapper_repr(textio *self)
29792984
if (res == NULL)
29802985
return NULL;
29812986

2982-
status = Py_ReprEnter((PyObject *)self);
2987+
status = Py_ReprEnter(op);
29832988
if (status != 0) {
29842989
if (status > 0) {
29852990
PyErr_Format(PyExc_RuntimeError,
@@ -2988,7 +2993,7 @@ textiowrapper_repr(textio *self)
29882993
}
29892994
goto error;
29902995
}
2991-
if (PyObject_GetOptionalAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) {
2996+
if (PyObject_GetOptionalAttr(op, &_Py_ID(name), &nameobj) < 0) {
29922997
if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
29932998
goto error;
29942999
}
@@ -3004,7 +3009,7 @@ textiowrapper_repr(textio *self)
30043009
if (res == NULL)
30053010
goto error;
30063011
}
3007-
if (PyObject_GetOptionalAttr((PyObject *) self, &_Py_ID(mode), &modeobj) < 0) {
3012+
if (PyObject_GetOptionalAttr(op, &_Py_ID(mode), &modeobj) < 0) {
30083013
goto error;
30093014
}
30103015
if (modeobj != NULL) {
@@ -3020,14 +3025,14 @@ textiowrapper_repr(textio *self)
30203025
res, self->encoding);
30213026
Py_DECREF(res);
30223027
if (status == 0) {
3023-
Py_ReprLeave((PyObject *)self);
3028+
Py_ReprLeave(op);
30243029
}
30253030
return s;
30263031

30273032
error:
30283033
Py_XDECREF(res);
30293034
if (status == 0) {
3030-
Py_ReprLeave((PyObject *)self);
3035+
Py_ReprLeave(op);
30313036
}
30323037
return NULL;
30333038
}
@@ -3167,9 +3172,10 @@ _io_TextIOWrapper_close_impl(textio *self)
31673172
}
31683173

31693174
static PyObject *
3170-
textiowrapper_iternext(textio *self)
3175+
textiowrapper_iternext(PyObject *op)
31713176
{
31723177
PyObject *line;
3178+
textio *self = _textio_CAST(op);
31733179

31743180
CHECK_ATTACHED(self);
31753181

@@ -3179,8 +3185,7 @@ textiowrapper_iternext(textio *self)
31793185
line = _textiowrapper_readline(self, -1);
31803186
}
31813187
else {
3182-
line = PyObject_CallMethodNoArgs((PyObject *)self,
3183-
&_Py_ID(readline));
3188+
line = PyObject_CallMethodNoArgs(op, &_Py_ID(readline));
31843189
if (line && !PyUnicode_Check(line)) {
31853190
PyErr_Format(PyExc_OSError,
31863191
"readline() should have returned a str object, "

0 commit comments

Comments
 (0)