From 33cf172df3c70e1d72b964b3446c050042d42981 Mon Sep 17 00:00:00 2001 From: Jokimax Date: Sat, 15 Apr 2023 17:35:50 +0300 Subject: [PATCH 1/5] gh-102956: Fix returning of empty byte strings after seek in zipfile module --- Lib/test/test_zipfile/test_core.py | 18 ++++++++++++++++++ Lib/zipfile/__init__.py | 10 +++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 73c6b0185a1a0e..62145e7317dffd 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2082,6 +2082,24 @@ def test_seek_tell(self): 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!') + fp.seek(-bloc, os.SEEK_CUR) + self.assertEqual(fp.read(-1), b'Charge 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 95c047991f872b..cac922c2f8b4a3 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -1117,8 +1117,12 @@ def seek(self, offset, whence=os.SEEK_SET): 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 @@ -1129,10 +1133,6 @@ def seek(self, offset, whence=os.SEEK_SET): # 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) From f3e77e64bd9f58d63461ddb67ea64a82a651bb14 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 15 Apr 2023 14:45:22 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst diff --git a/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst new file mode 100644 index 00000000000000..3133ff87d71f83 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst @@ -0,0 +1 @@ +Fixed returning of empty byte strings after seek in zipfile module(This wasn't in a release version so the news is not probably unnecessary) From e43f9bd824356238ece55e58c714f3fbd8bc8bbf Mon Sep 17 00:00:00 2001 From: Jokimax <77680901+Jokimax@users.noreply.github.com> Date: Sat, 15 Apr 2023 17:46:19 +0300 Subject: [PATCH 3/5] Update 2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst --- .../next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst index 3133ff87d71f83..144c1ac0b78211 100644 --- a/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst +++ b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst @@ -1 +1 @@ -Fixed returning of empty byte strings after seek in zipfile module(This wasn't in a release version so the news is not probably unnecessary) +Fixed returning of empty byte strings after seek in zipfile module(This wasn't in a release version so the news is probably unnecessary) From 662c4e66a798c9d3c39d1f5cf8779e034a120df2 Mon Sep 17 00:00:00 2001 From: Jokimax Date: Sat, 15 Apr 2023 19:43:28 +0300 Subject: [PATCH 4/5] gh-102956: Fix returning of empty byte strings after seek in zipfile module --- Lib/test/test_zipfile/test_core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 62145e7317dffd..b12e50cd7ba299 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2092,8 +2092,6 @@ def test_read_after_seek(self): with zipf.open("foo.txt", "r") as fp: fp.seek(bloc, os.SEEK_CUR) self.assertEqual(fp.read(-1), b'men!') - fp.seek(-bloc, os.SEEK_CUR) - self.assertEqual(fp.read(-1), b'Charge men!') with zipfile.ZipFile(TESTFN, mode="r") as zipf: with zipf.open("foo.txt", "r") as fp: fp.read(6) From af0d60a371c63d94160a0df18ec80034618e9c8d Mon Sep 17 00:00:00 2001 From: Jokimax <77680901+Jokimax@users.noreply.github.com> Date: Tue, 24 Oct 2023 18:32:27 +0300 Subject: [PATCH 5/5] Update Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst Co-authored-by: Alex Waygood --- .../next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst index 144c1ac0b78211..1a4bb9bc0dc46a 100644 --- a/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst +++ b/Misc/NEWS.d/next/Library/2023-04-15-14-45-21.gh-issue-102956.Z6qeUy.rst @@ -1 +1 @@ -Fixed returning of empty byte strings after seek in zipfile module(This wasn't in a release version so the news is probably unnecessary) +Fix returning of empty byte strings after seek in zipfile module