From 3763ea865cee5bbabcce11cd577811135e0fc747 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 6 May 2017 14:46:01 +0300 Subject: [PATCH] Revert bpo-26293 for zipfile breakage. See also bpo-29094. (#1484) --- Lib/zipfile.py | 27 +++++++++++++-------------- Misc/NEWS | 7 ------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 988f39ed1b1..cc46a6c1d9c 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1109,7 +1109,6 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True - self._start_disk = 0 try: self.start_dir = self.fp.tell() except (AttributeError, OSError): @@ -1135,7 +1134,7 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True - self.start_dir = self._start_disk = self.fp.tell() + self.start_dir = self.fp.tell() else: raise ValueError("Mode must be 'r', 'w', 'x', or 'a'") except: @@ -1179,18 +1178,17 @@ def _RealGetContents(self): offset_cd = endrec[_ECD_OFFSET] # offset of central directory self._comment = endrec[_ECD_COMMENT] # archive comment - # self._start_disk: Position of the start of ZIP archive - # It is zero, unless ZIP was concatenated to another file - self._start_disk = endrec[_ECD_LOCATION] - size_cd - offset_cd + # "concat" is zero, unless zip was concatenated to another file + concat = endrec[_ECD_LOCATION] - size_cd - offset_cd if endrec[_ECD_SIGNATURE] == stringEndArchive64: # If Zip64 extension structures are present, account for them - self._start_disk -= (sizeEndCentDir64 + sizeEndCentDir64Locator) + concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) if self.debug > 2: - inferred = self._start_disk + offset_cd - print("given, inferred, offset", offset_cd, inferred, self._start_disk) + inferred = concat + offset_cd + print("given, inferred, offset", offset_cd, inferred, concat) # self.start_dir: Position of start of central directory - self.start_dir = offset_cd + self._start_disk + self.start_dir = offset_cd + concat fp.seek(self.start_dir, 0) data = fp.read(size_cd) fp = io.BytesIO(data) @@ -1230,7 +1228,7 @@ def _RealGetContents(self): t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) x._decodeExtra() - x.header_offset = x.header_offset + self._start_disk + x.header_offset = x.header_offset + concat self.filelist.append(x) self.NameToInfo[x.filename] = x @@ -1701,10 +1699,11 @@ def _write_end_record(self): file_size = zinfo.file_size compress_size = zinfo.compress_size - header_offset = zinfo.header_offset - self._start_disk - if header_offset > ZIP64_LIMIT: - extra.append(header_offset) + if zinfo.header_offset > ZIP64_LIMIT: + extra.append(zinfo.header_offset) header_offset = 0xffffffff + else: + header_offset = zinfo.header_offset extra_data = zinfo.extra min_version = 0 @@ -1751,7 +1750,7 @@ def _write_end_record(self): # Write end-of-zip-archive record centDirCount = len(self.filelist) centDirSize = pos2 - self.start_dir - centDirOffset = self.start_dir - self._start_disk + centDirOffset = self.start_dir requires_zip64 = None if centDirCount > ZIP_FILECOUNT_LIMIT: requires_zip64 = "Files count" diff --git a/Misc/NEWS b/Misc/NEWS index 0c403cb0cf4..a72fceff10d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -602,9 +602,6 @@ Library - Issue #28985: Update authorizer constants in sqlite3 module. Patch by Dingyuan Wang. -- Issue #29094: Offsets in a ZIP file created with extern file object and modes - "w" and "x" now are relative to the start of the file. - - Issue #29079: Prevent infinite loop in pathlib.resolve() on Windows - Issue #13051: Fixed recursion errors in large or resized @@ -784,10 +781,6 @@ Library - Issue #28317: The disassembler now decodes FORMAT_VALUE argument. -- Issue #26293: Fixed writing ZIP files that starts not from the start of the - file. Offsets in ZIP file now are relative to the start of the archive in - conforming to the specification. - - Issue #28380: unittest.mock Mock autospec functions now properly support assert_called, assert_not_called, and assert_called_once.