Content-Length: 365773 | pFad | http://github.com/python/cpython/pull/14957/commits/46604e04cef1e8a24abb5096a55de4e291a4b6b2

2B bpo-37538: Zipfile refactor by danifus · Pull Request #14957 · python/cpython · GitHub
Skip to content

bpo-37538: Zipfile refactor #14957

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a0db1c9
Add descriptive global variables for general purpose bit flags
danifus Jul 10, 2019
6710baf
Add global variable for zip64 extra data header id
danifus Jul 10, 2019
3777389
Add flag properties to ZipInfo
danifus Jul 10, 2019
f435f08
Restructure how ZipExtFile gets created from ZipFile.open
danifus Jul 10, 2019
ca41137
Fix bug when seeking on encrypted zip files
danifus Jul 10, 2019
00c87ee
Refactor _ZipDecrypter with a BaseZipDecrypter class
danifus Jul 11, 2019
b8364a6
Move compressor and decompressor selection code into classes
danifus Jul 12, 2019
6b256c0
Add zipinfo_cls, zipextfile_cls and zipwritefile_cls to ZipFile
danifus Jul 12, 2019
af8864b
Fix typo datadescripter -> datadescriptor
danifus Jul 13, 2019
42c4be6
Add dosdate and dostime properties to ZipInfo
danifus Jul 13, 2019
801d966
Move encoding datadescriptor to ZipInfo
danifus Jul 13, 2019
46604e0
Refactor how ZipInfo encodes the local file header.
danifus Jul 13, 2019
7d28d8f
Move central directory encoding to ZipInfo
danifus Jul 14, 2019
c784d7f
Move struct packing of central directory record to a ZipInfo method
danifus Jul 14, 2019
f84e481
Refactor _decodeExtra to allow subclasses to support new extra fields
danifus Jul 14, 2019
1a07518
Change the way zipfile _decodeExtra loops through the extra bytes
danifus Jul 14, 2019
6de1a9a
Decouple updating and checking crc when reading a zipfile
danifus Jul 14, 2019
6b90dfd
Move writing zipfile local header to _ZipWriteFile
danifus Jul 14, 2019
4417cc5
Move writing local header to within _ZipWriteFile
danifus Jul 15, 2019
bfa8a7e
Add some comments to zipfile's LZMACompressor
danifus Jul 15, 2019
a211abe
Add comments to ZipFile._write_end_record describing structs
danifus Jul 17, 2019
3eff8be
Small performance fix to zipfile.CRCZipDecrypter
danifus Jul 22, 2019
7220ef9
Refactor ZipFile encoding approach
danifus Jul 22, 2019
0a718f7
Change ZipInfo encoding of local extra data
danifus Jul 22, 2019
cb826d6
Allow ZipFile _open_to_write() and _open_to_read() to take kwargs
danifus Jul 26, 2019
5a88b2d
Change ZipFile._open_to_write() to accept pwd argument.
danifus Jul 26, 2019
fa374ee
ZipFile remove special case path for ZIP_STORED
danifus Jul 26, 2019
5bb4c17
📜🤖 Added by blurb_it.
blurb-it[bot] Jul 26, 2019
366f79f
bpo-37538: Small clean up of zipfile refactor
danifus Jul 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor how ZipInfo encodes the local file header.
** This changes the default content of the `extra` field in the local
header to be empty **

Previously, if a file was opened via a ZipInfo instance that had data in
the `extra` field, we may have erroneously left the previous values
there while appending any new or modified values after the existing
content.

This behaviour differs to that of writing the central header `extra`
field where we check that a zip64 entry is not already present and
remove it if it is present (via `_strip_extra`). All other extra fields
are copied across in this instance (which may not be correct either).
  • Loading branch information
danifus committed Jul 26, 2019
commit 46604e04cef1e8a24abb5096a55de4e291a4b6b2
95 changes: 74 additions & 21 deletions Lib/zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,33 +481,79 @@ def dostime(self):
dt = self.date_time
return dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)

def FileHeader(self, zip64=None):
"""Return the per-file header as a bytes object."""
if self.use_datadescriptor:
# Set these to zero because we write them after the file data
CRC = compress_size = file_size = 0
else:
CRC = self.CRC
compress_size = self.compress_size
file_size = self.file_size
def encode_local_header(self, *, filename, extract_version, reserved,
flag_bits, compress_type, dostime, dosdate, crc,
compress_size, file_size, extra):
header = struct.pack(
structFileHeader,
stringFileHeader,
extract_version,
reserved,
flag_bits,
compress_type,
dostime,
dosdate,
crc,
compress_size,
file_size,
len(filename),
len(extra)
)
return header + filename + extra

extra = self.extra
def zip64_local_header(self, zip64, file_size, compress_size):
"""If zip64 is required, return encoded extra block and other
parameters which may alter the local file header.

The local zip64 entry requires that, if the zip64 block is present, it
must contain both file_size and compress_size. This is different to the
central directory zip64 extra block which requires only fields which
need the extra zip64 size be present in the extra block (zip app note
4.5.3).
"""
min_version = 0
requires_zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
if zip64 is None:
zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
zip64 = requires_zip64
if zip64:
fmt = '<HHQQ'
extra = extra + struct.pack(fmt,
1, struct.calcsize(fmt)-4, file_size, compress_size)
if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
extra = struct.pack(
'<HHQQ',
EXTRA_ZIP64,
16, # QQ
file_size,
compress_size
)
else:
extra = b''
if requires_zip64:
if not zip64:
raise LargeZipFile("Filesize would require ZIP64 extensions")
# File is larger than what fits into a 4 byte integer,
# fall back to the ZIP64 extension
file_size = 0xffffffff
compress_size = 0xffffffff
min_version = ZIP64_VERSION
return extra, file_size, compress_size, min_version

def FileHeader(self, zip64=None):
"""Return the per-file header as a bytes object."""
if self.use_datadescriptor:
# Set these to zero because we write them after the file data
CRC = compress_size = file_size = 0
else:
CRC = self.CRC
compress_size = self.compress_size
file_size = self.file_size

# There are reports that windows 7 can only read zip 64 archives if the
# zip 64 extra block is the first extra block present.
min_version = 0
(extra,
file_size,
compress_size,
zip64_min_version,
) = self.zip64_local_header(zip64, file_size, compress_size)
min_version = min(min_version, zip64_min_version)

if self.compress_type == ZIP_BZIP2:
min_version = max(BZIP2_VERSION, min_version)
Expand All @@ -517,12 +563,19 @@ def FileHeader(self, zip64=None):
self.extract_version = max(min_version, self.extract_version)
self.create_version = max(min_version, self.create_version)
filename, flag_bits = self._encodeFilenameFlags()
header = struct.pack(structFileHeader, stringFileHeader,
self.extract_version, self.reserved, flag_bits,
self.compress_type, self.dostime, self.dosdate,
CRC, compress_size, file_size,
len(filename), len(extra))
return header + filename + extra
return self.encode_local_header(
filename=filename,
extract_version=self.extract_version,
reserved=self.reserved,
flag_bits=flag_bits,
compress_type=self.compress_type,
dostime=self.dostime,
dosdate=self.dosdate,
crc=CRC,
compress_size=compress_size,
file_size=file_size,
extra=extra
)

def _encodeFilenameFlags(self):
try:
Expand Down








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/python/cpython/pull/14957/commits/46604e04cef1e8a24abb5096a55de4e291a4b6b2

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy