gh-108111: Flush gzip write buffer before seeking, fixing bad writes (#108341)

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Chris Markiewicz 2023-08-24 04:23:01 -04:00 committed by GitHub
parent aa9a359ca2
commit 2eb60c1934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 0 deletions

View File

@ -401,6 +401,9 @@ class GzipFile(_compression.BaseStream):
def seek(self, offset, whence=io.SEEK_SET): def seek(self, offset, whence=io.SEEK_SET):
if self.mode == WRITE: if self.mode == WRITE:
self._check_not_closed()
# Flush buffer to ensure validity of self.offset
self._buffer.flush()
if whence != io.SEEK_SET: if whence != io.SEEK_SET:
if whence == io.SEEK_CUR: if whence == io.SEEK_CUR:
offset = self.offset + offset offset = self.offset + offset

View File

@ -665,6 +665,18 @@ class TestGzip(BaseTest):
] ]
self.assertEqual(fc.modes, expected_modes) self.assertEqual(fc.modes, expected_modes)
def test_write_seek_write(self):
# Make sure that offset is up-to-date before seeking
# See issue GH-108111
b = io.BytesIO()
message = b"important message here."
with gzip.GzipFile(fileobj=b, mode='w') as f:
f.write(message)
f.seek(len(message))
f.write(message)
data = b.getvalue()
self.assertEqual(gzip.decompress(data), message * 2)
class TestOpen(BaseTest): class TestOpen(BaseTest):
def test_binary_modes(self): def test_binary_modes(self):

View File

@ -1150,6 +1150,7 @@ Colin Marc
Vincent Marchetti Vincent Marchetti
David Marek David Marek
Doug Marien Doug Marien
Chris Markiewicz
Sven Marnach Sven Marnach
John Marshall John Marshall
Alex Martelli Alex Martelli

View File

@ -0,0 +1,2 @@
Fix a regression introduced in GH-101251 for 3.12, resulting in an incorrect
offset calculation in :meth:`gzip.GzipFile.seek`.