summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_zipfile/test_core.py10
-rw-r--r--Lib/zipfile/__init__.py2
-rw-r--r--Misc/NEWS.d/next/Library/2024-07-29-15-20-30.gh-issue-122356.wKCmFx.rst3
3 files changed, 13 insertions, 2 deletions
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index 36f7f54..c36228c 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -1969,10 +1969,16 @@ class OtherTests(unittest.TestCase):
zip_contents = fp.read()
# - passing a file-like object
fp = io.BytesIO()
- fp.write(zip_contents)
+ end = fp.write(zip_contents)
+ self.assertEqual(fp.tell(), end)
+ mid = end // 2
+ fp.seek(mid, 0)
self.assertTrue(zipfile.is_zipfile(fp))
- fp.seek(0, 0)
+ # check that the position is left unchanged after the call
+ # see: https://github.com/python/cpython/issues/122356
+ self.assertEqual(fp.tell(), mid)
self.assertTrue(zipfile.is_zipfile(fp))
+ self.assertEqual(fp.tell(), mid)
def test_non_existent_file_raises_OSError(self):
# make sure we don't raise an AttributeError when a partially-constructed
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 08c83cf..6907ae6 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -241,7 +241,9 @@ def is_zipfile(filename):
result = False
try:
if hasattr(filename, "read"):
+ pos = filename.tell()
result = _check_zipfile(fp=filename)
+ filename.seek(pos)
else:
with open(filename, "rb") as fp:
result = _check_zipfile(fp)
diff --git a/Misc/NEWS.d/next/Library/2024-07-29-15-20-30.gh-issue-122356.wKCmFx.rst b/Misc/NEWS.d/next/Library/2024-07-29-15-20-30.gh-issue-122356.wKCmFx.rst
new file mode 100644
index 0000000..0a4632c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-29-15-20-30.gh-issue-122356.wKCmFx.rst
@@ -0,0 +1,3 @@
+Guarantee that the position of a file-like object passed to
+:func:`zipfile.is_zipfile` is left untouched after the call.
+Patch by Bénédikt Tran.