]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[2.7] bpo-25862: Fix several bugs in the _io module. (GH-8026) (GH-8033)
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 4 Dec 2018 10:02:48 +0000 (12:02 +0200)
committerGitHub <noreply@github.com>
Tue, 4 Dec 2018 10:02:48 +0000 (12:02 +0200)
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)

Modules/_io/stringio.c
Modules/_io/textio.c

index 83bb7acacbb8a11bd1f7255a0fae3e39de799950..c52ca27ad9d64a986dcdb64a0a4a5a75ee29267d 100644 (file)
@@ -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,
index 825e84937c15e727ac2f92709347eff677ec636e..5501da4b3f5cdcd6f6182e26f8b6ec0ae8281b20 100644 (file)
@@ -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) */