Issue #12062: 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).
This commit is contained in:
parent
0a42982316
commit
7c40489180
|
@ -1461,6 +1461,32 @@ class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest):
|
||||||
self.assertEqual(s,
|
self.assertEqual(s,
|
||||||
b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size))
|
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):
|
def test_truncate_after_read_or_write(self):
|
||||||
raw = self.BytesIO(b"A" * 10)
|
raw = self.BytesIO(b"A" * 10)
|
||||||
bufio = self.tp(raw, 100)
|
bufio = self.tp(raw, 100)
|
||||||
|
|
|
@ -69,6 +69,11 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #12062: 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 #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError.
|
- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError.
|
||||||
With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused
|
With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused
|
||||||
IDLE to exit. Converted to valid Unicode null in PythonCmd().
|
IDLE to exit. Converted to valid Unicode null in PythonCmd().
|
||||||
|
|
|
@ -1749,7 +1749,7 @@ bufferedwriter_write(buffered *self, PyObject *args)
|
||||||
avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
|
avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
|
||||||
if (buf.len <= avail) {
|
if (buf.len <= avail) {
|
||||||
memcpy(self->buffer + self->pos, buf.buf, buf.len);
|
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;
|
self->write_pos = self->pos;
|
||||||
}
|
}
|
||||||
ADJUST_POSITION(self, self->pos + buf.len);
|
ADJUST_POSITION(self, self->pos + buf.len);
|
||||||
|
|
Loading…
Reference in New Issue