mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
[3.12] gh-102956: Fix returning of empty byte strings after seek in zipfile … (GH-103565) (#111289)
gh-102956: Fix returning of empty byte strings after seek in zipfile … (GH-103565)
(cherry picked from commit c73b0f3560
)
gh-102956: Fix returning of empty byte strings after seek in zipfile module. This was a regression in 3.12.0 due to a performance enhancement.
Co-authored-by: Jokimax <77680901+Jokimax@users.noreply.github.com>
This commit is contained in:
parent
a4eb2e308d
commit
6f130f231b
3 changed files with 22 additions and 5 deletions
|
@ -2246,6 +2246,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'
|
||||
|
|
|
@ -1122,8 +1122,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
|
||||
|
@ -1134,10 +1138,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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fix returning of empty byte strings after seek in zipfile module
|
Loading…
Add table
Add a link
Reference in a new issue