Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c739f18 authored by Kelvin Zhang's avatar Kelvin Zhang
Browse files

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
parent 0bf992ee
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -2114,17 +2114,28 @@ def UnzipToDir(filename, dirname, patterns=None):
  """
  with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip:
    # 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:
      names = input_zip.namelist()
      filtered = [name for name in names if any(
          [fnmatch.fnmatch(name, p) for p in patterns])]
      filtered = [info for info in entries if any(
          [fnmatch.fnmatch(info.filename, p) for p in patterns])]

      # There isn't any matching files. Don't unzip anything.
      if not filtered:
        return
      input_zip.extractall(dirname, filtered)
    else:
      input_zip.extractall(dirname)
      input_zip.extractall(dirname, entries)


def UnzipTemp(filename, patterns=None):