From 813523730ad42a37c177e7c579b2b2f2de875927 Mon Sep 17 00:00:00 2001 From: Dima Ryazanov Date: Wed, 11 Dec 2024 23:22:38 -0800 Subject: [PATCH 1/6] gh-127847: Fix position in the special-cased zipfile seek --- Lib/test/test_zipfile/test_core.py | 12 ++++++++++++ Lib/zipfile/__init__.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index c36228c033a414..e419dd25952dc0 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2333,6 +2333,18 @@ def test_read_after_seek(self): fp.seek(1, os.SEEK_CUR) self.assertEqual(fp.read(-1), b'men!') + def test_uncompressed_interleaved_seek_read(self): + # Issue 127847: Make sure the position in the archive is correct + # in the special case of seeking in a ZIP_STORED entry. + with zipfile.ZipFile(TESTFN, "w") as zipf: + zipf.writestr("a.txt", "123") + zipf.writestr("b.txt", "456") + with zipfile.ZipFile(TESTFN, "r") as zipf: + with zipf.open("a.txt", "r") as a, zipf.open("b.txt", "r") as b: + a.read(1) + b.seek(1) + self.assertEqual(b.read(1), b"5") + @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 6907ae6d5b7464..3810fa95916cdf 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -1167,7 +1167,7 @@ def seek(self, offset, whence=os.SEEK_SET): self._expected_crc = None # seek actual file taking already buffered data into account read_offset -= len(self._readbuffer) - self._offset - self._fileobj.seek(read_offset, os.SEEK_CUR) + self._fileobj.seek(self._orig_compress_start + read_offset) self._left -= read_offset read_offset = 0 # flush read buffer From 3f8837a54f5f92f694e97bed80612180d7a8c899 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 07:27:52 +0000 Subject: [PATCH 2/6] =?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 --- .../2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst new file mode 100644 index 00000000000000..82e969e78a5d6f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst @@ -0,0 +1 @@ +Fix the position when doing interleaved seeks and reads in uncompressed unencrypted zip files From fecb892643813ce88a111ddf8d1fe20bc93e8c5d Mon Sep 17 00:00:00 2001 From: Dima Ryazanov Date: Wed, 11 Dec 2024 23:31:35 -0800 Subject: [PATCH 3/6] move the blurb to the correct directory --- .../2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Core_and_Builtins => Library}/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst (100%) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst b/Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst similarity index 100% rename from Misc/NEWS.d/next/Core_and_Builtins/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst rename to Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst From bc2bd58b2739a4eb9d796b0e081cbb1c668cc72f Mon Sep 17 00:00:00 2001 From: Dima Ryazanov Date: Thu, 12 Dec 2024 13:39:52 -0800 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Peter Bierma --- Lib/test/test_zipfile/test_core.py | 2 +- .../next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index e419dd25952dc0..81b6987ba7988a 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2334,7 +2334,7 @@ def test_read_after_seek(self): self.assertEqual(fp.read(-1), b'men!') def test_uncompressed_interleaved_seek_read(self): - # Issue 127847: Make sure the position in the archive is correct + # gh-127847: Make sure the position in the archive is correct # in the special case of seeking in a ZIP_STORED entry. with zipfile.ZipFile(TESTFN, "w") as zipf: zipf.writestr("a.txt", "123") diff --git a/Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst b/Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst index 82e969e78a5d6f..3d6e36fb538bca 100644 --- a/Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst +++ b/Misc/NEWS.d/next/Library/2024-12-12-07-27-51.gh-issue-127847.ksfNKM.rst @@ -1 +1 @@ -Fix the position when doing interleaved seeks and reads in uncompressed unencrypted zip files +Fix the position when doing interleaved seeks and reads in uncompressed, unencrypted zip files returned by :meth:`zipfile.ZipFile.open`. From 2835a4a4854446e025a872b79478474c52abfe7c Mon Sep 17 00:00:00 2001 From: Dima Ryazanov Date: Thu, 12 Dec 2024 13:38:56 -0800 Subject: [PATCH 5/6] add more asserts --- Lib/test/test_zipfile/test_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 81b6987ba7988a..124e088fd15b80 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -2341,8 +2341,8 @@ def test_uncompressed_interleaved_seek_read(self): zipf.writestr("b.txt", "456") with zipfile.ZipFile(TESTFN, "r") as zipf: with zipf.open("a.txt", "r") as a, zipf.open("b.txt", "r") as b: - a.read(1) - b.seek(1) + self.assertEqual(a.read(1), b"1") + self.assertEqual(b.seek(1), 1) self.assertEqual(b.read(1), b"5") @requires_bz2() From 4cfd007c53ae98f23adba5fac5d9f550fe750c71 Mon Sep 17 00:00:00 2001 From: Dima Ryazanov Date: Thu, 12 Dec 2024 21:52:02 -0800 Subject: [PATCH 6/6] move the fix into _SharedFile --- Lib/zipfile/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 3810fa95916cdf..f4d396abb6e639 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -819,7 +819,10 @@ def seek(self, offset, whence=0): raise ValueError("Can't reposition in the ZIP file while " "there is an open writing handle on it. " "Close the writing handle before trying to read.") - self._file.seek(offset, whence) + if whence == os.SEEK_CUR: + self._file.seek(self._pos + offset) + else: + self._file.seek(offset, whence) self._pos = self._file.tell() return self._pos @@ -1167,7 +1170,7 @@ def seek(self, offset, whence=os.SEEK_SET): self._expected_crc = None # seek actual file taking already buffered data into account read_offset -= len(self._readbuffer) - self._offset - self._fileobj.seek(self._orig_compress_start + read_offset) + self._fileobj.seek(read_offset, os.SEEK_CUR) self._left -= read_offset read_offset = 0 # flush read buffer