diff options
author | Jokimax <jonaxthedreadlord@gmail.com> | 2023-04-15 17:35:50 +0300 |
---|---|---|
committer | Michał Górny <mgorny@gentoo.org> | 2023-10-24 16:27:44 +0200 |
commit | da3b4274ef4dadbe86d33901bf13d654bc3bc104 (patch) | |
tree | 0cd6feb6eda2e40a3a9b1cadc99a0cb481fad4d6 | |
parent | Prevent tests from detecting our fake tzdata package (diff) | |
download | cpython-gentoo-3.12.0_p1.tar.gz cpython-gentoo-3.12.0_p1.tar.bz2 cpython-gentoo-3.12.0_p1.zip |
gh-102956: Fix returning of empty byte strings after seek in zipfile modulegentoo-3.12.0_p1
Taken from https://github.com/python/cpython/pull/103565
-rw-r--r-- | Lib/test/test_zipfile/test_core.py | 16 | ||||
-rw-r--r-- | Lib/zipfile/__init__.py | 10 |
2 files changed, 21 insertions, 5 deletions
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 9960259c4cd..186471c5084 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2235,6 +2235,22 @@ class OtherTests(unittest.TestCase): fp.seek(0, os.SEEK_SET) self.assertEqual(fp.tell(), 0) + def test_read_after_seek(self): + # Issue 102956: Make sure seek(x, os.SEEK_CUR) doesn't break read() + txt = b"Charge men!" + bloc = txt.find(b"men") + with zipfile.ZipFile(TESTFN, "w") as zipf: + zipf.writestr("foo.txt", txt) + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + with zipf.open("foo.txt", "r") as fp: + fp.seek(bloc, os.SEEK_CUR) + self.assertEqual(fp.read(-1), b'men!') + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + with zipf.open("foo.txt", "r") as fp: + fp.read(6) + fp.seek(1, os.SEEK_CUR) + self.assertEqual(fp.read(-1), b'men!') + @requires_bz2() def test_decompress_without_3rd_party_library(self): data = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 9fc1840ba1e..38acddb97e9 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -1121,8 +1121,12 @@ class ZipExtFile(io.BufferedIOBase): read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset + if buff_offset >= 0 and buff_offset < len(self._readbuffer): + # Just move the _offset index if the new position is in the _readbuffer + self._offset = buff_offset + read_offset = 0 # Fast seek uncompressed unencrypted file - if self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: + elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: # disable CRC checking after first seeking - it would be invalid self._expected_crc = None # seek actual file taking already buffered data into account @@ -1133,10 +1137,6 @@ class ZipExtFile(io.BufferedIOBase): # flush read buffer self._readbuffer = b'' self._offset = 0 - elif buff_offset >= 0 and buff_offset < len(self._readbuffer): - # Just move the _offset index if the new position is in the _readbuffer - self._offset = buff_offset - read_offset = 0 elif read_offset < 0: # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) |