[Python-checkins] bpo-25862: Fix several bugs in the _io module. (GH-8026)

Serhiy Storchaka webhook-mailer at python.org
Sat Jun 30 13:57:53 EDT 2018


https://github.com/python/cpython/commit/fdb5a50ef34f7951c3b01eb77b1359725a9ad670
commit: fdb5a50ef34f7951c3b01eb77b1359725a9ad670
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-06-30T20:57:50+03:00
summary:

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().

files:
M Modules/_io/stringio.c
M Modules/_io/textio.c

diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index f280b30c812a..5a03715fbde0 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 6e706cdeb60a..a466d3a03a5b 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) */



More information about the Python-checkins mailing list