diff options
author | Kelvin Zhang <zhangkelvin@google.com> | 2023-06-17 09:18:15 -0700 |
---|---|---|
committer | Kelvin Zhang <zhangkelvin@google.com> | 2023-07-17 14:08:24 -0700 |
commit | e66c973a36339484e8fa59c37c9005badca62a5d (patch) | |
tree | b70a33c52caa0288b83b69b887d5a52a59ecea27 | |
parent | 3c739f18475a9d31be299f3016dddc6a5ac02e16 (diff) | |
download | build-e66c973a36339484e8fa59c37c9005badca62a5d.tar.gz |
Handle zip64 extra fields better
Test: check_target_files_signatures
Bug: 283033491
(cherry picked from https://android-review.googlesource.com/q/commit:1e774245a4dd2763545827d65462e5c115eecb63)
Merged-In: I7da89f8389c09cc99201cff342483c158bd7e9c1
Change-Id: I7da89f8389c09cc99201cff342483c158bd7e9c1
-rwxr-xr-x | tools/releasetools/check_target_files_signatures.py | 5 | ||||
-rw-r--r-- | tools/releasetools/common.py | 18 |
2 files changed, 19 insertions, 4 deletions
diff --git a/tools/releasetools/check_target_files_signatures.py b/tools/releasetools/check_target_files_signatures.py index d935607e43..a7b35230ea 100755 --- a/tools/releasetools/check_target_files_signatures.py +++ b/tools/releasetools/check_target_files_signatures.py @@ -241,7 +241,8 @@ class APK(object): # Signer (minSdkVersion=24, maxSdkVersion=32) certificate SHA-1 digest: 19da94896ce4078c38ca695701f1dec741ec6d67 # ... certs_info = {} - certificate_regex = re.compile(r"(Signer (?:#[0-9]+|\(.*\))) (certificate .*):(.*)") + certificate_regex = re.compile( + r"(Signer (?:#[0-9]+|\(.*\))) (certificate .*):(.*)") for line in output.splitlines(): m = certificate_regex.match(line) if not m: @@ -312,7 +313,7 @@ class TargetFiles(object): # This is the list of wildcards of files we extract from |filename|. apk_extensions = ['*.apk', '*.apex'] - with zipfile.ZipFile(filename) as input_zip: + with zipfile.ZipFile(filename, "r") as input_zip: self.certmap, compressed_extension = common.ReadApkCerts(input_zip) if compressed_extension: apk_extensions.append('*.apk' + compressed_extension) diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index f2e77756b0..477bf4ea9d 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -2123,9 +2123,23 @@ def UnzipToDir(filename, dirname, patterns=None): # 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. + + # ZIP64 central directory extra field has two required fields: + # 2 bytes header ID and 2 bytes size field. Thes two require fields have + # a total size of 4 bytes. Then it has three other 8 bytes field, followed + # by a 4 byte disk number field. The last disk number field is not required + # to be present, but if it is present, the total size of extra field will be + # divisible by 8(because 2+2+4+8*n is always going to be multiple of 8) + # Most extra fields are optional, but when they appear, their must appear + # in the order defined by zip64 spec. Since file header offset is the 2nd + # to last field in zip64 spec, it will only be at last 8 bytes or last 12-4 + # bytes, depending on whether disk number is present. 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 entry.header_offset == 0xFFFFFFFF: + if len(entry.extra) % 8 == 0: + entry.header_offset = int.from_bytes(entry.extra[-12:-4], "little") + else: + entry.header_offset = int.from_bytes(entry.extra[-8:], "little") if patterns is not None: filtered = [info for info in entries if any( [fnmatch.fnmatch(info.filename, p) for p in patterns])] |