Skip to content

Commit eab421b

Browse files
[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 fdb5a50)
1 parent 8687bd8 commit eab421b

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

‎Modules/_io/stringio.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,10 @@ stringio_getstate(stringio *self)
693693
}
694694
else {
695695
dict = PyDict_Copy(self->dict);
696-
if (dict == NULL)
696+
if (dict == NULL) {
697+
Py_DECREF(initvalue);
697698
return NULL;
699+
}
698700
}
699701

700702
state = Py_BuildValue("(OOnN)", initvalue,

‎Modules/_io/textio.c‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,7 @@ textiowrapper_read_chunk(textio *self)
14661466
/* At the snapshot point, len(dec_buffer) bytes before the read, the
14671467
* next input to be decoded is dec_buffer + input_chunk.
14681468
*/
1469+
PyObject *snapshot;
14691470
PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk);
14701471
if (next_input == NULL)
14711472
goto fail;
@@ -1477,8 +1478,13 @@ textiowrapper_read_chunk(textio *self)
14771478
Py_DECREF(next_input);
14781479
goto fail;
14791480
}
1481+
snapshot = Py_BuildValue("NN", dec_flags, next_input);
1482+
if (snapshot == NULL) {
1483+
dec_flags = NULL;
1484+
goto fail;
1485+
}
1486+
Py_XSETREF(self->snapshot, snapshot);
14801487
Py_DECREF(dec_buffer);
1481-
Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input));
14821488
}
14831489
Py_DECREF(input_chunk);
14841490

@@ -2013,6 +2019,7 @@ textiowrapper_seek(textio *self, PyObject *args)
20132019
int whence = 0;
20142020
PyObject *res;
20152021
int cmp;
2022+
PyObject *snapshot;
20162023

20172024
CHECK_ATTACHED(self);
20182025

@@ -2149,11 +2156,11 @@ textiowrapper_seek(textio *self, PyObject *args)
21492156
goto fail;
21502157
}
21512158

2152-
self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2153-
if (self->snapshot == NULL) {
2154-
Py_DECREF(input_chunk);
2159+
snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2160+
if (snapshot == NULL) {
21552161
goto fail;
21562162
}
2163+
Py_XSETREF(self->snapshot, snapshot);
21572164

21582165
decoded = PyObject_CallMethod(self->decoder, "decode",
21592166
"Oi", input_chunk, (int)cookie.need_eof);
@@ -2171,9 +2178,10 @@ textiowrapper_seek(textio *self, PyObject *args)
21712178
self->decoded_chars_used = cookie.chars_to_skip;
21722179
}
21732180
else {
2174-
self->snapshot = Py_BuildValue("is", cookie.dec_flags, "");
2175-
if (self->snapshot == NULL)
2181+
snapshot = Py_BuildValue("is", cookie.dec_flags, "");
2182+
if (snapshot == NULL)
21762183
goto fail;
2184+
Py_XSETREF(self->snapshot, snapshot);
21772185
}
21782186

21792187
/* Finally, reset the encoder (merely useful for proper BOM handling) */

0 commit comments

Comments
 (0)