aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJokimax <jonaxthedreadlord@gmail.com>2023-04-15 17:35:50 +0300
committerMichał Górny <mgorny@gentoo.org>2023-10-24 16:27:44 +0200
commitda3b4274ef4dadbe86d33901bf13d654bc3bc104 (patch)
tree0cd6feb6eda2e40a3a9b1cadc99a0cb481fad4d6
parentPrevent tests from detecting our fake tzdata package (diff)
downloadcpython-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.py16
-rw-r--r--Lib/zipfile/__init__.py10
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)