summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-12-04 12:02:48 +0200
committerGitHub <noreply@github.com>2018-12-04 12:02:48 +0200
commiteab421bff954e4fb77516bfe6c98d30ced1412d0 (patch)
tree81cb028d6f947bd1c345f2e4957fca153553b208
parent8687bd86e6f138ef0699a1e9f3f9555765949b51 (diff)
downloadcpython-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.c4
-rw-r--r--Modules/_io/textio.c20
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) */