diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-13 18:02:33 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-13 18:02:33 (GMT) |
commit | 56452eea39baa9d1864b2275b9e93cf37378af09 (patch) | |
tree | e2e7758ebbb55ef1a8539178a1941565e2ec63c2 /Modules/_io/textio.c | |
parent | 682d05528ecd5e4ccdbce5bc90edec1a4fd1d71d (diff) | |
parent | 85e3ee749c351ebe0ad1ec28856d64da50b13f20 (diff) | |
download | cpython-56452eea39baa9d1864b2275b9e93cf37378af09.zip cpython-56452eea39baa9d1864b2275b9e93cf37378af09.tar.gz cpython-56452eea39baa9d1864b2275b9e93cf37378af09.tar.bz2 |
Issue #22982: Improve BOM handling when seeking to multiple positions of a writable text file.
Diffstat (limited to 'Modules/_io/textio.c')
-rw-r--r-- | Modules/_io/textio.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index af232bf..67ac445 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -2048,11 +2048,10 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) } static int -_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) +_textiowrapper_encoder_reset(textio *self, int start_of_stream) { PyObject *res; - /* Same as _textiowrapper_decoder_setstate() above. */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) { + if (start_of_stream) { res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL); self->encoding_start_of_stream = 1; } @@ -2067,6 +2066,14 @@ _textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) return 0; } +static int +_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) +{ + /* Same as _textiowrapper_decoder_setstate() above. */ + return _textiowrapper_encoder_reset( + self, cookie->start_pos == 0 && cookie->dec_flags == 0); +} + static PyObject * textiowrapper_seek(textio *self, PyObject *args) { @@ -2134,7 +2141,17 @@ textiowrapper_seek(textio *self, PyObject *args) } res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); - Py_XDECREF(cookieObj); + Py_CLEAR(cookieObj); + if (res == NULL) + goto fail; + if (self->encoder) { + /* If seek() == 0, we are at the start of stream, otherwise not */ + cmp = PyObject_RichCompareBool(res, _PyIO_zero, Py_EQ); + if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) { + Py_DECREF(res); + goto fail; + } + } return res; } else if (whence != 0) { |