diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-12-04 12:02:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-04 12:02:48 +0200 |
commit | eab421bff954e4fb77516bfe6c98d30ced1412d0 (patch) | |
tree | 81cb028d6f947bd1c345f2e4957fca153553b208 | |
parent | 8687bd86e6f138ef0699a1e9f3f9555765949b51 (diff) | |
download | cpython-git-eab421bff954e4fb77516bfe6c98d30ced1412d0.tar.gz |
[2.7] bpo-25862: Fix several bugs in the _io module. (GH-8026) (GH-8033)
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().
* initvalue could leak in StringIO.__getstate__() after failed
PyDict_Copy().
(cherry picked from commit fdb5a50ef34f7951c3b01eb77b1359725a9ad670)
-rw-r--r-- | Modules/_io/stringio.c | 4 | ||||
-rw-r--r-- | Modules/_io/textio.c | 20 |
2 files changed, 17 insertions, 7 deletions
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 83bb7acacb..c52ca27ad9 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -693,8 +693,10 @@ stringio_getstate(stringio *self) } 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 825e84937c..5501da4b3f 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1466,6 +1466,7 @@ textiowrapper_read_chunk(textio *self) /* At the snapshot point, len(dec_buffer) bytes before the read, the * next input to be decoded is dec_buffer + input_chunk. */ + PyObject *snapshot; PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk); if (next_input == NULL) goto fail; @@ -1477,8 +1478,13 @@ textiowrapper_read_chunk(textio *self) Py_DECREF(next_input); goto fail; } + snapshot = Py_BuildValue("NN", dec_flags, next_input); + if (snapshot == NULL) { + dec_flags = NULL; + goto fail; + } + Py_XSETREF(self->snapshot, snapshot); Py_DECREF(dec_buffer); - Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input)); } Py_DECREF(input_chunk); @@ -2013,6 +2019,7 @@ textiowrapper_seek(textio *self, PyObject *args) int whence = 0; PyObject *res; int cmp; + PyObject *snapshot; CHECK_ATTACHED(self); @@ -2149,11 +2156,11 @@ textiowrapper_seek(textio *self, PyObject *args) 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_CallMethod(self->decoder, "decode", "Oi", input_chunk, (int)cookie.need_eof); @@ -2171,9 +2178,10 @@ textiowrapper_seek(textio *self, PyObject *args) self->decoded_chars_used = cookie.chars_to_skip; } else { - self->snapshot = Py_BuildValue("is", cookie.dec_flags, ""); - if (self->snapshot == NULL) + snapshot = Py_BuildValue("is", cookie.dec_flags, ""); + if (snapshot == NULL) goto fail; + Py_XSETREF(self->snapshot, snapshot); } /* Finally, reset the encoder (merely useful for proper BOM handling) */ |