diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index ada96813709aea..20ef72baa1dd52 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -3505,12 +3505,28 @@ def test_data_offset_write_with_prefix(self): fp.write(b"this is a prefix") with zipfile.ZipFile(fp, "w") as zipfp: self.assertEqual(zipfp.data_offset, 16) + fp.seek(0) + with zipfile.ZipFile(fp) as zipfp: + self.assertEqual(zipfp.data_offset, 16) + + def test_data_offset_write_with_prefix_and_entry(self): + with io.BytesIO() as fp: + fp.write(b"this is a prefix") + with zipfile.ZipFile(fp, "w") as zipfp: + self.assertEqual(zipfp.data_offset, 16) + zipfp.writestr("test.txt", "content") + fp.seek(0) + with zipfile.ZipFile(fp) as zipfp: + self.assertEqual(zipfp.data_offset, 16) def test_data_offset_append_with_bad_zip(self): with io.BytesIO() as fp: fp.write(b"this is a prefix") with zipfile.ZipFile(fp, "a") as zipfp: self.assertEqual(zipfp.data_offset, 16) + fp.seek(0) + with zipfile.ZipFile(fp) as zipfp: + self.assertEqual(zipfp.data_offset, 16) def test_data_offset_write_no_tell(self): # The initializer in ZipFile checks if tell raises AttributeError or diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 18caeb3e04a2b5..fc6c252864477b 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -1535,10 +1535,6 @@ def _RealGetContents(self): # self.start_dir: Position of start of central directory self.start_dir = offset_cd + concat - # store the offset to the beginning of data for the - # .data_offset property - self._data_offset = concat - if self.start_dir < 0: raise BadZipFile("Bad offset for central directory") fp.seek(self.start_dir, 0) @@ -1594,11 +1590,19 @@ def _RealGetContents(self): print("total", total) end_offset = self.start_dir + zinfo = None for zinfo in reversed(sorted(self.filelist, key=lambda zinfo: zinfo.header_offset)): zinfo._end_offset = end_offset end_offset = zinfo.header_offset + # store the offset to the beginning of data for the + # .data_offset property + if zinfo is None: + self._data_offset = self.start_dir + else: + self._data_offset = zinfo.header_offset + @property def data_offset(self): """The offset to the start of zip data in the file or None if