mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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.
This commit is contained in:
parent
cf3806026b
commit
8793b21525
3 changed files with 62 additions and 15 deletions
|
@ -1029,10 +1029,10 @@ class ZipFile:
|
|||
# even if no files are added to the archive
|
||||
self._didModify = True
|
||||
try:
|
||||
self.start_dir = self.fp.tell()
|
||||
self.start_dir = self._start_disk = self.fp.tell()
|
||||
except (AttributeError, OSError):
|
||||
self.fp = _Tellable(self.fp)
|
||||
self.start_dir = 0
|
||||
self.start_dir = self._start_disk = 0
|
||||
self._seekable = False
|
||||
else:
|
||||
# Some file-like objects can provide tell() but not seek()
|
||||
|
@ -1053,7 +1053,7 @@ class ZipFile:
|
|||
# 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.fp.tell()
|
||||
self.start_dir = self._start_disk = self.fp.tell()
|
||||
else:
|
||||
raise RuntimeError("Mode must be 'r', 'w', 'x', or 'a'")
|
||||
except:
|
||||
|
@ -1097,17 +1097,18 @@ class ZipFile:
|
|||
offset_cd = endrec[_ECD_OFFSET] # offset of central directory
|
||||
self._comment = endrec[_ECD_COMMENT] # archive comment
|
||||
|
||||
# "concat" is zero, unless zip was concatenated to another file
|
||||
concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
|
||||
# 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
|
||||
if endrec[_ECD_SIGNATURE] == stringEndArchive64:
|
||||
# If Zip64 extension structures are present, account for them
|
||||
concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
|
||||
self._start_disk -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
|
||||
|
||||
if self.debug > 2:
|
||||
inferred = concat + offset_cd
|
||||
print("given, inferred, offset", offset_cd, inferred, concat)
|
||||
inferred = self._start_disk + offset_cd
|
||||
print("given, inferred, offset", offset_cd, inferred, self._start_disk)
|
||||
# self.start_dir: Position of start of central directory
|
||||
self.start_dir = offset_cd + concat
|
||||
self.start_dir = offset_cd + self._start_disk
|
||||
fp.seek(self.start_dir, 0)
|
||||
data = fp.read(size_cd)
|
||||
fp = io.BytesIO(data)
|
||||
|
@ -1147,7 +1148,7 @@ class ZipFile:
|
|||
t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )
|
||||
|
||||
x._decodeExtra()
|
||||
x.header_offset = x.header_offset + concat
|
||||
x.header_offset = x.header_offset + self._start_disk
|
||||
self.filelist.append(x)
|
||||
self.NameToInfo[x.filename] = x
|
||||
|
||||
|
@ -1627,11 +1628,10 @@ class ZipFile:
|
|||
file_size = zinfo.file_size
|
||||
compress_size = zinfo.compress_size
|
||||
|
||||
if zinfo.header_offset > ZIP64_LIMIT:
|
||||
extra.append(zinfo.header_offset)
|
||||
header_offset = zinfo.header_offset - self._start_disk
|
||||
if header_offset > ZIP64_LIMIT:
|
||||
extra.append(header_offset)
|
||||
header_offset = 0xffffffff
|
||||
else:
|
||||
header_offset = zinfo.header_offset
|
||||
|
||||
extra_data = zinfo.extra
|
||||
min_version = 0
|
||||
|
@ -1678,7 +1678,7 @@ class ZipFile:
|
|||
# Write end-of-zip-archive record
|
||||
centDirCount = len(self.filelist)
|
||||
centDirSize = pos2 - self.start_dir
|
||||
centDirOffset = self.start_dir
|
||||
centDirOffset = self.start_dir - self._start_disk
|
||||
requires_zip64 = None
|
||||
if centDirCount > ZIP_FILECOUNT_LIMIT:
|
||||
requires_zip64 = "Files count"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue