Skip to content

Commit 725b1a3

Browse files
committed
Update data_offset
1 parent 8e69c09 commit 725b1a3

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

Lib/test/test_zipfile/test_core.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2001,8 +2001,8 @@ def test_repack_prepended_bytes(self):
20012001
for ii in ([], [0], [0, 1], [1], [2]):
20022002
with self.subTest(remove=ii):
20032003
# calculate the expected results
2004-
test_files = [data for j, data in enumerate(self.test_files) if j not in ii]
20052004
fz = io.BytesIO()
2005+
test_files = [data for j, data in enumerate(self.test_files) if j not in ii]
20062006
self._prepare_zip_from_test_files(fz, test_files)
20072007
fz.seek(0)
20082008
with open(TESTFN, 'wb') as fh:
@@ -2020,9 +2020,64 @@ def test_repack_prepended_bytes(self):
20202020
fh.write(b'dummy ')
20212021
fh.write(fz.read())
20222022
with zipfile.ZipFile(TESTFN, 'a', self.compression) as zh:
2023+
self.assertEqual(zh.data_offset, 6)
20232024
for i in ii:
20242025
zh.remove(self.test_files[i][0])
20252026
zh.repack()
2027+
if hasattr(zh, 'data_offset'):
2028+
self.assertEqual(zh.data_offset, 6)
2029+
2030+
# check infolist
2031+
self.assertEqual(
2032+
[ComparableZipInfo(zi) for zi in zh.infolist()],
2033+
[ComparableZipInfo(zi) for zi in expected_zinfos],
2034+
)
2035+
2036+
# check file size
2037+
self.assertEqual(os.path.getsize(TESTFN), expected_size)
2038+
2039+
# make sure the zip file is still valid
2040+
with zipfile.ZipFile(TESTFN) as zh:
2041+
self.assertIsNone(zh.testzip())
2042+
2043+
def test_repack_prepended_file_entry(self):
2044+
for ii in ([0], [0, 1], [0, 1, 2]):
2045+
with self.subTest(remove=ii):
2046+
# calculate the expected results
2047+
fz = io.BytesIO()
2048+
test_files = [data for j, data in enumerate(self.test_files) if j not in ii]
2049+
self._prepare_zip_from_test_files(fz, test_files)
2050+
fz.seek(0)
2051+
with open(TESTFN, 'wb') as fh:
2052+
fh.write(b'dummy ')
2053+
fh.write(fz.read())
2054+
with zipfile.ZipFile(TESTFN) as zh:
2055+
expected_zinfos = list(zh.infolist())
2056+
expected_size = os.path.getsize(TESTFN)
2057+
2058+
# do the removal and check the result
2059+
fz = io.BytesIO()
2060+
with zipfile.ZipFile(fz, 'w') as zh:
2061+
for j, (file, data) in enumerate(self.test_files):
2062+
if j in ii:
2063+
zh.writestr(file, data)
2064+
fz.seek(0)
2065+
prefix = fz.read()
2066+
2067+
fz = io.BytesIO()
2068+
test_files = [data for j, data in enumerate(self.test_files) if j not in ii]
2069+
self._prepare_zip_from_test_files(fz, test_files)
2070+
fz.seek(0)
2071+
2072+
with open(TESTFN, 'wb') as fh:
2073+
fh.write(b'dummy ')
2074+
fh.write(prefix)
2075+
fh.write(fz.read())
2076+
2077+
with zipfile.ZipFile(TESTFN, 'a', self.compression) as zh:
2078+
self.assertEqual(zh.data_offset, 6 + len(prefix))
2079+
zh.repack()
2080+
self.assertEqual(zh.data_offset, 6)
20262081

20272082
# check infolist
20282083
self.assertEqual(
@@ -2212,8 +2267,10 @@ def test_repack_removed_prepended_bytes(self):
22122267
fh.write(b'dummy ')
22132268
fh.write(fz.read())
22142269
with zipfile.ZipFile(TESTFN, 'a', self.compression) as zh:
2270+
self.assertEqual(zh.data_offset, 6)
22152271
zinfos = [zh.remove(self.test_files[i][0]) for i in ii]
22162272
zh.repack(zinfos)
2273+
self.assertEqual(zh.data_offset, 6)
22172274

22182275
# check infolist
22192276
self.assertEqual(

Lib/zipfile/__init__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,8 @@ def repack(self, zfile, removed=None):
14531453
14541454
Side effects:
14551455
- Modifies the ZIP file in place.
1456-
- Updates zfile.start_dir to account for removed data.
1456+
- Updates zfile.start_dir and zfile.data_offset to account for
1457+
removed data.
14571458
- Sets zfile._didModify to True.
14581459
- Updates header_offset and clears _end_offset of referenced
14591460
ZipInfo instances.
@@ -1558,6 +1559,14 @@ def repack(self, zfile, removed=None):
15581559
zfile.start_dir -= entry_offset
15591560
zfile._didModify = True
15601561

1562+
if zfile._data_offset:
1563+
try:
1564+
offset = filelist[0].header_offset
1565+
except IndexError:
1566+
offset = zfile.start_dir
1567+
if offset < zfile._data_offset:
1568+
zfile._data_offset = offset
1569+
15611570
for zinfo in filelist:
15621571
zinfo._end_offset = None
15631572

0 commit comments

Comments
 (0)