diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-05-13 00:31:52 +0200 |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-05-13 00:31:52 +0200 |
commit | 1b737dd131e1395800f53df0de7b06b2fcecb678 (patch) | |
tree | 262be0b5c8a3d995c6663253c31d8ee104336c9a | |
parent | 994268f6858412d618168e07fa316cf0e236df8f (diff) | |
download | cpython-1b737dd131e1395800f53df0de7b06b2fcecb678.tar.gz |
Issue #12062: In the `io` module, fix a flushing bug when doing a certain
type of I/O sequence on a file opened in read+write mode (namely: reading,
seeking a bit forward, writing, then seeking before the previous write but
still within buffered data, and writing again).
-rw-r--r-- | Lib/test/test_io.py | 26 | ||||
-rw-r--r-- | Misc/NEWS | 5 | ||||
-rw-r--r-- | Modules/_io/bufferedio.c | 2 |
3 files changed, 32 insertions, 1 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 0bad56deba..8af8a64622 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1462,6 +1462,32 @@ class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest): self.assertEqual(s, b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size)) + def test_write_rewind_write(self): + # Various combinations of reading / writing / seeking backwards / writing again + def mutate(bufio, pos1, pos2): + assert pos2 >= pos1 + # Fill the buffer + bufio.seek(pos1) + bufio.read(pos2 - pos1) + bufio.write(b'\x02') + # This writes earlier than the previous write, but still inside + # the buffer. + bufio.seek(pos1) + bufio.write(b'\x01') + + b = b"\x80\x81\x82\x83\x84" + for i in range(0, len(b)): + for j in range(i, len(b)): + raw = self.BytesIO(b) + bufio = self.tp(raw, 100) + mutate(bufio, i, j) + bufio.flush() + expected = bytearray(b) + expected[j] = 2 + expected[i] = 1 + self.assertEqual(raw.getvalue(), expected, + "failed result for i=%d, j=%d" % (i, j)) + def test_truncate_after_read_or_write(self): raw = self.BytesIO(b"A" * 10) bufio = self.tp(raw, 100) @@ -80,6 +80,11 @@ Core and Builtins Library ------- +- Issue #12062: In the `io` module, fix a flushing bug when doing a certain + type of I/O sequence on a file opened in read+write mode (namely: reading, + seeking a bit forward, writing, then seeking before the previous write but + still within buffered data, and writing again). + - Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in order to accept exactly one connection. Patch by Daniel Evers. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 5816a93432..144aea20d8 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1810,7 +1810,7 @@ bufferedwriter_write(buffered *self, PyObject *args) avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); if (buf.len <= avail) { memcpy(self->buffer + self->pos, buf.buf, buf.len); - if (!VALID_WRITE_BUFFER(self)) { + if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) { self->write_pos = self->pos; } ADJUST_POSITION(self, self->pos + buf.len); |