From 048e7ca15f6391681490ce564bc71194adf146aa Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Mon, 15 Jun 2009 14:31:53 -0700 Subject: [PATCH] fix archive files being created with perms 000 In python 2.5 and earlier, ZipFile.writestr(filename, data) results in the file being added to the archive with permissions 000. (See http://svn.python.org/view?view=rev&revision=65235.) Work around this by creating a ZipInfo object and setting the permissions explicitly. --- tools/releasetools/common.py | 12 +++++++++++- tools/releasetools/img_from_target_files | 2 +- tools/releasetools/ota_from_target_files | 21 +++++++++------------ tools/releasetools/sign_target_files_apks | 6 +++--- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 686c6eff28..033ba22ab3 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -21,6 +21,7 @@ import shutil import subprocess import sys import tempfile +import zipfile # missing in Python 2.4 and before if not hasattr(os, "SEEK_SET"): @@ -70,7 +71,7 @@ def BuildAndAddBootableImage(sourcedir, targetname, output_zip): img = BuildBootableImage(sourcedir) CheckSize(img, targetname) - output_zip.writestr(targetname, img) + ZipWriteStr(output_zip, targetname, img) def BuildBootableImage(sourcedir): """Take a kernel, cmdline, and ramdisk directory from the input (in @@ -381,3 +382,12 @@ class PasswordManager(object): if e.errno != errno.ENOENT: print "error reading password file: ", str(e) return result + + +def ZipWriteStr(zip, filename, data, perms=0644): + # use a fixed timestamp so the output is repeatable. + zinfo = zipfile.ZipInfo(filename=filename, + date_time=(2009, 1, 1, 0, 0, 0)) + zinfo.compress_type = zip.compression + zinfo.external_attr = perms << 16 + zip.writestr(zinfo, data) diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files index 345135237a..1d154b9d91 100755 --- a/tools/releasetools/img_from_target_files +++ b/tools/releasetools/img_from_target_files @@ -96,7 +96,7 @@ def AddSystem(output_zip): img.close() common.CheckSize(data, "system.img") - output_zip.writestr("system.img", data) + common.ZipWriteStr(output_zip, "system.img", data) def CopyInfo(output_zip): diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files index 7e36da2c19..1ac035a1f2 100755 --- a/tools/releasetools/ota_from_target_files +++ b/tools/releasetools/ota_from_target_files @@ -267,11 +267,8 @@ def CopySystemFiles(input_zip, output_zip=None, def AddScript(script, output_zip): - now = time.localtime() - i = zipfile.ZipInfo("META-INF/com/google/android/update-script", - (now.tm_year, now.tm_mon, now.tm_mday, - now.tm_hour, now.tm_min, now.tm_sec)) - output_zip.writestr(i, "\n".join(script) + "\n") + common.ZipWriteStr(output_zip, "META-INF/com/google/android/update-script", + "\n".join(script) + "\n") def SignOutput(temp_zip_name, output_zip_name): @@ -328,7 +325,7 @@ def IncludeBinary(name, input_zip, output_zip, input_path=None): data = open(input_path).read() else: data = input_zip.read(os.path.join("OTA/bin", name)) - output_zip.writestr(name, data) + common.ZipWriteStr(output_zip, name, data, perms=0755) except IOError: raise ExternalError('unable to include device binary "%s"' % (name,)) @@ -346,7 +343,7 @@ def WriteFullOTAPackage(input_zip, output_zip): script.append("format BOOT:") script.append("show_progress 0.1 0") - output_zip.writestr("radio.img", input_zip.read("RADIO/image")) + common.ZipWriteStr(output_zip, "radio.img", input_zip.read("RADIO/image")) script.append("write_radio_image PACKAGE:radio.img") script.append("show_progress 0.5 0") @@ -390,7 +387,7 @@ class File(object): return t def AddToZip(self, z): - z.writestr(self.name, self.data) + common.ZipWriteStr(z, self.name, self.data) def LoadSystemFiles(z): @@ -486,7 +483,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): tf.AddToZip(output_zip) verbatim_targets.append((fn, tf.size)) else: - output_zip.writestr("patch/" + fn + ".p", d) + common.ZipWriteStr(output_zip, "patch/" + fn + ".p", d) patch_list.append((fn, tf, sf, tf.size)) largest_source_size = max(largest_source_size, sf.size) else: @@ -552,7 +549,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): print "recovery target: %d source: %d diff: %d" % ( target_recovery.size, source_recovery.size, len(d)) - output_zip.writestr("patch/recovery.img.p", d) + common.ZipWriteStr(output_zip, "patch/recovery.img.p", d) script.append(("run_program PACKAGE:applypatch -c " "MTD:recovery:%d:%s:%d:%s") % @@ -564,7 +561,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): print "boot target: %d source: %d diff: %d" % ( target_boot.size, source_boot.size, len(d)) - output_zip.writestr("patch/boot.img.p", d) + common.ZipWriteStr(output_zip, "patch/boot.img.p", d) script.append(("run_program PACKAGE:applypatch -c " "MTD:boot:%d:%s:%d:%s") % @@ -617,7 +614,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): if updating_radio: script.append("show_progress 0.3 10") script.append("write_radio_image PACKAGE:radio.img") - output_zip.writestr("radio.img", target_radio) + common.ZipWriteStr(output_zip, "radio.img", target_radio) print "radio image changed; including." else: print "radio image unchanged; skipping." diff --git a/tools/releasetools/sign_target_files_apks b/tools/releasetools/sign_target_files_apks index 9f393c80db..bc04956258 100755 --- a/tools/releasetools/sign_target_files_apks +++ b/tools/releasetools/sign_target_files_apks @@ -283,7 +283,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip): data, _ = p.communicate() if p.returncode != 0: raise ExternalError("failed to run dumpkeys") - output_tf_zip.writestr("RECOVERY/RAMDISK/res/keys", data) + common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data) # SystemUpdateActivity uses the x509.pem version of the keys, but # put into a zipfile system/etc/security/otacerts.zip. @@ -293,8 +293,8 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip): for k in mapped_keys: certs_zip.write(k) certs_zip.close() - output_tf_zip.writestr("SYSTEM/etc/security/otacerts.zip", - tempfile.getvalue()) + common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip", + tempfile.getvalue()) def main(argv):