aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-06-30 11:25:37 -0700
committerGitHub <noreply@github.com>2018-06-30 11:25:37 -0700
commitdedb28efd84314d899f795e821a3fc27d2f928e7 (patch)
tree19568d821f293b3cd5bdcaf267b1d0ff0fc951d0 /Modules/_io
parentbpo-32568: make select.epoll() and its docs consistent (GH-7840) (GH-8024) (diff)
downloadcpython-dedb28efd84314d899f795e821a3fc27d2f928e7.tar.gz
cpython-dedb28efd84314d899f795e821a3fc27d2f928e7.tar.bz2
cpython-dedb28efd84314d899f795e821a3fc27d2f928e7.zip
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(). (cherry picked from commit fdb5a50ef34f7951c3b01eb77b1359725a9ad670) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Modules/_io')
-rw-r--r--Modules/_io/stringio.c4
-rw-r--r--Modules/_io/textio.c21
2 files changed, 17 insertions, 8 deletions
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index 718b1ac1d82..460442f29d1 100644
--- a/Modules/_io/stringio.c
+++ b/Modules/_io/stringio.c
@@ -826,8 +826,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 fa162e2c6fa..d6b1e943788 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) */