diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-06-30 17:57:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-30 17:57:50 (GMT) |
commit | fdb5a50ef34f7951c3b01eb77b1359725a9ad670 (patch) | |
tree | 772e7c9d7632341fcf835dbbe84fbc4736ec9466 /Modules/_io | |
parent | 0cdf5f42898350261c5ff65d96334e736130780f (diff) | |
download | cpython-fdb5a50ef34f7951c3b01eb77b1359725a9ad670.zip cpython-fdb5a50ef34f7951c3b01eb77b1359725a9ad670.tar.gz cpython-fdb5a50ef34f7951c3b01eb77b1359725a9ad670.tar.bz2 |
bpo-25862: Fix several bugs in the _io module. (GH-8026)
They can be exposed when some C API calls fail due to lack of
memory.
* Failed Py_BuildValue() could cause an assertion error in the
following TextIOWrapper.tell().
* input_chunk could be decrefed twice in TextIOWrapper.seek()
after failed Py_BuildValue().
* initvalue could leak in StringIO.__getstate__() after failed
PyDict_Copy().
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/stringio.c | 4 | ||||
-rw-r--r-- | Modules/_io/textio.c | 21 |
2 files changed, 17 insertions, 8 deletions
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index f280b30..5a03715 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -826,8 +826,10 @@ stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) } else { dict = PyDict_Copy(self->dict); - if (dict == NULL) + if (dict == NULL) { + Py_DECREF(initvalue); return NULL; + } } state = Py_BuildValue("(OOnN)", initvalue, diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 6e706cd..a466d3a 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1773,11 +1773,16 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) */ PyObject *next_input = dec_buffer; PyBytes_Concat(&next_input, input_chunk); + dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ if (next_input == NULL) { - dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ goto fail; } - Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input)); + PyObject *snapshot = Py_BuildValue("NN", dec_flags, next_input); + if (snapshot == NULL) { + dec_flags = NULL; + goto fail; + } + Py_XSETREF(self->snapshot, snapshot); } Py_DECREF(input_chunk); @@ -2326,6 +2331,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) cookie_type cookie; PyObject *res; int cmp; + PyObject *snapshot; CHECK_ATTACHED(self); CHECK_CLOSED(self); @@ -2460,11 +2466,11 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); - if (self->snapshot == NULL) { - Py_DECREF(input_chunk); + snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); + if (snapshot == NULL) { goto fail; } + Py_XSETREF(self->snapshot, snapshot); decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode, "Oi", input_chunk, (int)cookie.need_eof); @@ -2482,9 +2488,10 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) self->decoded_chars_used = cookie.chars_to_skip; } else { - self->snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); - if (self->snapshot == NULL) + snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); + if (snapshot == NULL) goto fail; + Py_XSETREF(self->snapshot, snapshot); } /* Finally, reset the encoder (merely useful for proper BOM handling) */ |