Fix python3.11's support for zip64
Bug: 283033491 Test: check_target_files_signatures -v -l (cherry picked from https://android-review.googlesource.com/q/commit:38d0c373ac9e0f00c6e677c41bbc85f0e364ba02) Merged-In: I9c1a5346e3a5f3920242dc9a5268d999f50a4937 Change-Id: I9c1a5346e3a5f3920242dc9a5268d999f50a4937
This commit is contained in:
committed by
Cherrypicker Worker
parent
566cad2cb3
commit
77a6eb6276
@@ -2114,17 +2114,28 @@ def UnzipToDir(filename, dirname, patterns=None):
|
|||||||
"""
|
"""
|
||||||
with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip:
|
with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip:
|
||||||
# Filter out non-matching patterns. unzip will complain otherwise.
|
# Filter out non-matching patterns. unzip will complain otherwise.
|
||||||
|
entries = input_zip.infolist()
|
||||||
|
# b/283033491
|
||||||
|
# Per https://en.wikipedia.org/wiki/ZIP_(file_format)#Central_directory_file_header
|
||||||
|
# In zip64 mode, central directory record's header_offset field might be
|
||||||
|
# set to 0xFFFFFFFF if header offset is > 2^32. In this case, the extra
|
||||||
|
# fields will contain an 8 byte little endian integer at offset 20
|
||||||
|
# to indicate the actual local header offset.
|
||||||
|
# As of python3.11, python does not handle zip64 central directories
|
||||||
|
# correctly, so we will manually do the parsing here.
|
||||||
|
for entry in entries:
|
||||||
|
if entry.header_offset == 0xFFFFFFFF and len(entry.extra) >= 28:
|
||||||
|
entry.header_offset = int.from_bytes(entry.extra[20:28], "little")
|
||||||
if patterns is not None:
|
if patterns is not None:
|
||||||
names = input_zip.namelist()
|
filtered = [info for info in entries if any(
|
||||||
filtered = [name for name in names if any(
|
[fnmatch.fnmatch(info.filename, p) for p in patterns])]
|
||||||
[fnmatch.fnmatch(name, p) for p in patterns])]
|
|
||||||
|
|
||||||
# There isn't any matching files. Don't unzip anything.
|
# There isn't any matching files. Don't unzip anything.
|
||||||
if not filtered:
|
if not filtered:
|
||||||
return
|
return
|
||||||
input_zip.extractall(dirname, filtered)
|
input_zip.extractall(dirname, filtered)
|
||||||
else:
|
else:
|
||||||
input_zip.extractall(dirname)
|
input_zip.extractall(dirname, entries)
|
||||||
|
|
||||||
|
|
||||||
def UnzipTemp(filename, patterns=None):
|
def UnzipTemp(filename, patterns=None):
|
||||||
|
Reference in New Issue
Block a user