Skip to content

Commit 6cd1d6c

Browse files
authored
gh-84481: Make ZipFile.data_offset more robust (#132178)
1 parent 4084416 commit 6cd1d6c

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

Lib/test/test_zipfile/test_core.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,12 @@ def test_data_offset_write_with_prefix(self):
33483348
with zipfile.ZipFile(fp, "w") as zipfp:
33493349
self.assertEqual(zipfp.data_offset, 16)
33503350

3351+
def test_data_offset_append_with_bad_zip(self):
3352+
with io.BytesIO() as fp:
3353+
fp.write(b"this is a prefix")
3354+
with zipfile.ZipFile(fp, "a") as zipfp:
3355+
self.assertEqual(zipfp.data_offset, 16)
3356+
33513357
def test_data_offset_write_no_tell(self):
33523358
# The initializer in ZipFile checks if tell raises AttributeError or
33533359
# OSError when creating a file in write mode when deducing the offset
@@ -3357,7 +3363,7 @@ def tell(self):
33573363
raise OSError("Unimplemented!")
33583364
with NoTellBytesIO() as fp:
33593365
with zipfile.ZipFile(fp, "w") as zipfp:
3360-
self.assertIs(zipfp.data_offset, None)
3366+
self.assertIsNone(zipfp.data_offset)
33613367

33623368

33633369
class EncodedMetadataTests(unittest.TestCase):

Lib/zipfile/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,7 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
14031403
self._lock = threading.RLock()
14041404
self._seekable = True
14051405
self._writing = False
1406+
self._data_offset = None
14061407

14071408
try:
14081409
if mode == 'r':
@@ -1418,7 +1419,6 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
14181419
self.fp = _Tellable(self.fp)
14191420
self.start_dir = 0
14201421
self._seekable = False
1421-
self._data_offset = None
14221422
else:
14231423
# Some file-like objects can provide tell() but not seek()
14241424
try:
@@ -1439,6 +1439,7 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
14391439
# even if no files are added to the archive
14401440
self._didModify = True
14411441
self.start_dir = self.fp.tell()
1442+
self._data_offset = self.start_dir
14421443
else:
14431444
raise ValueError("Mode must be 'r', 'w', 'x', or 'a'")
14441445
except:

0 commit comments

Comments
 (0)