From 3c2c064c8791ed2d4b9d6780d7b87f406ab78f10 Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Tue, 27 Oct 2015 16:25:29 -0700 Subject: [PATCH] Remove changing uids/timestamps from zip/jar files Pass -X to zip so that Unix UID/GID and extra timestamps aren't saved into the zip files. Add a new option to zipalign, -t, to replace all timestamps with static timestamps (2008 Jan 1 00:00:00). Use this for all non-APK zip files. APK zip timestamps are set based on the certificate date in SignApk. Bug: 24201956 Change-Id: Ifb619fc499ba9d99fc624f2acd5f8de36d78ef8e --- core/Makefile | 52 +++++++++++++++++------------ core/definitions.mk | 17 ++++++++-- core/droiddoc.mk | 2 +- core/java_library.mk | 3 +- core/tasks/cts.mk | 2 +- core/tasks/sdk-addon.mk | 4 +-- core/tasks/tools/package-modules.mk | 2 +- tools/zipalign/README.txt | 3 ++ tools/zipalign/ZipAlign.cpp | 20 +++++++---- tools/zipalign/ZipEntry.cpp | 8 +++++ tools/zipalign/ZipEntry.h | 6 ++++ tools/zipalign/ZipFile.cpp | 19 ++++++++--- tools/zipalign/ZipFile.h | 23 +++++++------ 13 files changed, 108 insertions(+), 53 deletions(-) diff --git a/core/Makefile b/core/Makefile index d94318de7..4f219beb3 100644 --- a/core/Makefile +++ b/core/Makefile @@ -666,12 +666,18 @@ $(kernel_notice_file): \ # # This rule adds to ALL_DEFAULT_INSTALLED_MODULES, so it needs to come # before the rules that use that variable to build the image. -ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/security/otacerts.zip -$(TARGET_OUT_ETC)/security/otacerts.zip: KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR) -$(TARGET_OUT_ETC)/security/otacerts.zip: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR)) +OTACERTS_ZIP_BUILT := $(call intermediates-dir-for,PACKAGING,otacerts)/otacerts.zip +OTACERTS_ZIP := $(TARGET_OUT_ETC)/security/otacerts.zip +ALL_DEFAULT_INSTALLED_MODULES += $(OTACERTS_ZIP) + +$(OTACERTS_ZIP_BUILT): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR) +$(OTACERTS_ZIP_BUILT): $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR)) | $(ZIPALIGN) $(hide) rm -f $@ $(hide) mkdir -p $(dir $@) - $(hide) zip -qj $@ $< + $(hide) zip -qjX $@ $< + $(remove-timestamps-from-package) + +$(eval $(call copy-one-file,$(OTACERTS_ZIP_BUILT),$(OTACERTS_ZIP))) .PHONY: otacerts otacerts: $(TARGET_OUT_ETC)/security/otacerts.zip @@ -928,9 +934,13 @@ $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \ $(call build-recoveryimage-target, $@) ifneq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true) -$(RECOVERY_RESOURCE_ZIP): $(INSTALLED_RECOVERYIMAGE_TARGET) +RECOVERY_RESOURCE_ZIP_BUILT := $(call intermediates-dir-for,PACKAGING,recovery_resource)/recovery_resource.zip +$(RECOVERY_RESOURCE_ZIP_BUILT): $(INSTALLED_RECOVERYIMAGE_TARGET) | $(ZIPALIGN) $(hide) mkdir -p $(dir $@) - $(hide) find $(TARGET_RECOVERY_ROOT_OUT)/res -type f | sort | zip -0qrj $@ -@ + $(hide) find $(TARGET_RECOVERY_ROOT_OUT)/res -type f | sort | zip -0qrjX $@ -@ + $(remove-timestamps-from-package) + +$(eval $(call copy-one-file,$(RECOVERY_RESOURCE_ZIP_BUILT),$(RECOVERY_RESOURCE_ZIP))) endif .PHONY: recoveryimage-nodeps @@ -1121,19 +1131,19 @@ INSTALLED_PLATFORM_ZIP := $(PRODUCT_OUT)/platform.zip $(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_SYSTEMIMAGE_FILES) $(call pretty,"Platform zip package: $(INSTALLED_PLATFORM_ZIP)") $(hide) rm -f $@ - $(hide) cd $(dir $@) && zip -qry $(notdir $@) \ + $(hide) cd $(dir $@) && zip -qryX $(notdir $@) \ $(TARGET_COPY_OUT_SYSTEM) \ $(patsubst $(PRODUCT_OUT)/%, %, $(TARGET_OUT_NOTICE_FILES)) \ $(addprefix symbols/,$(PDK_SYMBOL_FILES_LIST)) ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE - $(hide) cd $(dir $@) && zip -qry $(notdir $@) \ + $(hide) cd $(dir $@) && zip -qryX $(notdir $@) \ $(TARGET_COPY_OUT_VENDOR) endif ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),) - $(hide) cd $(OUT_DIR) && zip -qry $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS) + $(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS) endif ifneq ($(PDK_PLATFORM_ZIP_PRODUCT_BINARIES),) - $(hide) zip -qry $@ $(PDK_PLATFORM_ZIP_PRODUCT_BINARIES) + $(hide) zip -qryX $@ $(PDK_PLATFORM_ZIP_PRODUCT_BINARIES) endif .PHONY: platform @@ -1402,9 +1412,9 @@ $(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) | $(ACP) $(hide) $(ACP) -p system/extras/verity/build_verity_metadata.py $(zip_root)/system/extras/verity/ $(hide) $(ACP) -r -d -p build/tools/releasetools/* $(zip_root)/releasetools $(hide) rm -rf $@ $(zip_root)/releasetools/*.pyc - $(hide) (cd $(zip_root) && zip -qry $(abspath $@) *) - $(hide) zip -qry $(abspath $@) build/target/product/security/ - $(hide) find device vendor -name \*.pk8 -o -name \*.x509.pem -o -name oem.prop | xargs zip -qry $(abspath $@)>/dev/null || true + $(hide) (cd $(zip_root) && zip -qryX $(abspath $@) *) + $(hide) zip -qryX $(abspath $@) build/target/product/security/ + $(hide) find device vendor -name \*.pk8 -o -name \*.x509.pem -o -name oem.prop | xargs zip -qryX $(abspath $@)>/dev/null || true .PHONY: otatools-package otatools-package: $(BUILT_OTATOOLS_PACKAGE) @@ -1626,7 +1636,7 @@ ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true) $(hide) $(ACP) -r $(TARGET_OUT_BREAKPAD) $(zip_root)/BREAKPAD endif @# Zip everything up, preserving symlinks - $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .) + $(hide) (cd $(zip_root) && zip -qryX ../$(notdir $@) .) @# Run fs_config on all the system, vendor, boot ramdisk, @# and recovery ramdisk files in the zip, and save the output $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt @@ -1639,7 +1649,7 @@ endif ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),) $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt endif - $(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt) + $(hide) (cd $(zip_root) && zip -qX ../$(notdir $@) META/*filesystem_config.txt) $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \ ./build/tools/releasetools/add_img_to_target_files -v -p $(HOST_OUT) $@ @@ -1719,7 +1729,7 @@ $(SYMBOLS_ZIP): @echo "Package symbols: $@" $(hide) rm -rf $@ $(hide) mkdir -p $(dir $@) $(TARGET_OUT_UNSTRIPPED) - $(hide) zip -qr $@ $(TARGET_OUT_UNSTRIPPED) + $(hide) zip -qrX $@ $(TARGET_OUT_UNSTRIPPED) # ----------------------------------------------------------------- # A zip of the Android Apps. Not keeping full path so that we don't @@ -1736,7 +1746,7 @@ $(APPS_ZIP): $(INSTALLED_SYSTEMIMAGE) @echo "Package apps: $@" $(hide) rm -rf $@ $(hide) mkdir -p $(dir $@) - $(hide) zip -qj $@ $(TARGET_OUT_APPS)/*/*.apk $(TARGET_OUT_APPS_PRIVILEGED)/*/*.apk + $(hide) zip -qjX $@ $(TARGET_OUT_APPS)/*/*.apk $(TARGET_OUT_APPS_PRIVILEGED)/*/*.apk #------------------------------------------------------------------ @@ -1749,7 +1759,7 @@ EMMA_META_ZIP := $(PRODUCT_OUT)/emma_meta.zip $(EMMA_META_ZIP) : @echo "Collecting Emma coverage meta files." $(hide) find $(TARGET_COMMON_OUT_ROOT) $(HOST_COMMON_OUT_ROOT) -name "coverage.em" | \ - zip -@ -q $@ + zip -@ -qX $@ endif # EMMA_INSTRUMENT=true @@ -1765,7 +1775,7 @@ $(PROGUARD_DICT_ZIP) : $(hide) dict_files=`find $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS -name proguard_dictionary`; \ if [ -n "$$dict_files" ]; then \ unobfuscated_jars=$${dict_files//proguard_dictionary/classes.jar}; \ - zip -q $@ $$dict_files $$unobfuscated_jars; \ + zip -qX $@ $$dict_files $$unobfuscated_jars; \ else \ touch $(dir $@)/zipdummy; \ (cd $(dir $@) && zip -q $(notdir $@) zipdummy); \ @@ -1796,7 +1806,7 @@ INTERNAL_EMULATOR_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip $(INTERNAL_EMULATOR_PACKAGE_TARGET): $(INTERNAL_EMULATOR_PACKAGE_FILES) @echo "Package: $@" - $(hide) zip -qj $@ $(INTERNAL_EMULATOR_PACKAGE_FILES) + $(hide) zip -qjX $@ $(INTERNAL_EMULATOR_PACKAGE_FILES) endif # ----------------------------------------------------------------- @@ -1931,7 +1941,7 @@ $(INTERNAL_SDK_TARGET): $(deps) HOST_OUT_EXECUTABLES=$(HOST_OUT_EXECUTABLES) HOST_OS=$(HOST_OS) \ development/build/tools/sdk_clean.sh $(PRIVATE_DIR) && \ chmod -R ug+rwX $(PRIVATE_DIR) && \ - cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME) \ + cd $(dir $@) && zip -rqX $(notdir $@) $(PRIVATE_NAME) \ ) || ( rm -rf $(PRIVATE_DIR) $@ && exit 44 ) diff --git a/core/definitions.mk b/core/definitions.mk index ecc72532d..b45039448 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -2094,13 +2094,13 @@ $(hide) mkdir -p $(addprefix $(dir $@)lib/,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)) $(foreach abi,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI),\ $(call _add-jni-shared-libs-to-package-per-abi,$(abi),\ $(patsubst $(abi):%,%,$(filter $(abi):%,$(PRIVATE_JNI_SHARED_LIBRARIES))))) -$(hide) (cd $(dir $@) && zip -qr $(JNI_COMPRESS_FLAGS) $(notdir $@) lib) +$(hide) (cd $(dir $@) && zip -qrX $(JNI_COMPRESS_FLAGS) $(notdir $@) lib) $(hide) rm -rf $(dir $@)lib endef #TODO: update the manifest to point to the dex file define add-dex-to-package -$(hide) zip -qj $@ $(dir $(PRIVATE_DEX_FILE))classes*.dex +$(hide) zip -qjX $@ $(dir $(PRIVATE_DEX_FILE))classes*.dex endef # Add java resources added by the current module. @@ -2147,6 +2147,17 @@ $(hide) $(ZIPALIGN) \ $(hide) mv $@.aligned $@ endef +# Remove dynamic timestamps from packages +# +define remove-timestamps-from-package +$(hide) mv $@ $@.timed +$(hide) $(ZIPALIGN) \ + -f -t \ + 1 \ + $@.timed $@.untimed +$(hide) mv $@.untimed $@ +endef + # Uncompress shared libraries embedded in an apk. # define uncompress-shared-libs @@ -2154,7 +2165,7 @@ $(hide) if unzip -l $@ $(PRIVATE_EMBEDDED_JNI_LIBS) >/dev/null ; then \ rm -rf $(dir $@)uncompressedlibs && mkdir $(dir $@)uncompressedlibs; \ unzip $@ $(PRIVATE_EMBEDDED_JNI_LIBS) -d $(dir $@)uncompressedlibs && \ zip -d $@ 'lib/*.so' && \ - ( cd $(dir $@)uncompressedlibs && zip -D -r -0 ../$(notdir $@) lib ) && \ + ( cd $(dir $@)uncompressedlibs && zip -D -r -X -0 ../$(notdir $@) lib ) && \ rm -rf $(dir $@)uncompressedlibs; \ fi endef diff --git a/core/droiddoc.mk b/core/droiddoc.mk index cc2a915d8..74f7d8b74 100644 --- a/core/droiddoc.mk +++ b/core/droiddoc.mk @@ -241,7 +241,7 @@ $(out_zip): $(full_target) @echo Package docs: $@ @rm -f $@ @mkdir -p $(dir $@) - $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rq $$F * ) + $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rqX $$F * ) $(LOCAL_MODULE)-docs.zip : $(out_zip) diff --git a/core/java_library.mk b/core/java_library.mk index 5a2d19bff..0ce7dfe7d 100644 --- a/core/java_library.mk +++ b/core/java_library.mk @@ -81,7 +81,7 @@ else # !LOCAL_IS_STATIC_JAVA_LIBRARY $(common_javalib.jar): PRIVATE_DEX_FILE := $(built_dex) $(common_javalib.jar): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar) $(common_javalib.jar): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS) -$(common_javalib.jar) : $(built_dex) $(java_resource_sources) +$(common_javalib.jar) : $(built_dex) $(java_resource_sources) | $(ZIPALIGN) @echo "target Jar: $(PRIVATE_MODULE) ($@)" ifdef LOCAL_JACK_ENABLED $(create-empty-package) @@ -92,6 +92,7 @@ endif ifdef LOCAL_JACK_ENABLED $(add-carried-jack-resources) endif + $(remove-timestamps-from-package) ifdef LOCAL_DEX_PREOPT ifneq ($(dexpreopt_boot_jar_module),) # boot jar diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk index 56a7f6fd4..38f130171 100644 --- a/core/tasks/cts.mk +++ b/core/tasks/cts.mk @@ -387,7 +387,7 @@ $(INTERNAL_CTS_TARGET): PRIVATE_DIR := $(cts_dir)/$(cts_name) $(INTERNAL_CTS_TARGET): TMP_DIR := $(cts_dir)/temp $(INTERNAL_CTS_TARGET): $(cts_dir)/all_cts_files_stamp $(DEFAULT_TEST_PLAN) $(hide) echo "Package CTS: $@" - $(hide) cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME) + $(hide) cd $(dir $@) && zip -rqX $(notdir $@) $(PRIVATE_NAME) .PHONY: cts cts: $(INTERNAL_CTS_TARGET) adb diff --git a/core/tasks/sdk-addon.mk b/core/tasks/sdk-addon.mk index 5ac9b7d47..362b22935 100644 --- a/core/tasks/sdk-addon.mk +++ b/core/tasks/sdk-addon.mk @@ -111,13 +111,13 @@ $(full_target): $(sdk_addon_deps) | $(ACP) $(ACP) -r $$d $(PRIVATE_STAGING_DIR)/docs ;\ done $(hide) mkdir -p $(dir $@) - $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rq $$F $(notdir $(PRIVATE_STAGING_DIR)) ) + $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rqX $$F $(notdir $(PRIVATE_STAGING_DIR)) ) $(full_target_img): PRIVATE_STAGING_DIR := $(call append-path,$(staging),$(addon_dir_img))/images/$(TARGET_CPU_ABI) $(full_target_img): $(full_target) $(addon_img_source_prop) @echo Packaging SDK Addon System-Image: $@ $(hide) mkdir -p $(dir $@) - $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rq $$F $(notdir $(PRIVATE_STAGING_DIR)) ) + $(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rqX $$F $(notdir $(PRIVATE_STAGING_DIR)) ) .PHONY: sdk_addon diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk index a70e644e4..24a7608b2 100644 --- a/core/tasks/tools/package-modules.mk +++ b/core/tasks/tools/package-modules.mk @@ -59,4 +59,4 @@ $(my_package_zip) : $(my_built_modules) $(call copy-tests-in-batch,$(wordlist 1201,9999,$(PRIVATE_COPY_PAIRS))) $(hide) $(foreach f, $(PRIVATE_PICKUP_FILES),\ cp -RfL $(f) $(dir $@);) - $(hide) cd $(dir $@) && zip -rq $(notdir $@) * + $(hide) cd $(dir $@) && zip -rqX $(notdir $@) * diff --git a/tools/zipalign/README.txt b/tools/zipalign/README.txt index 0b80b3535..1cdf61213 100644 --- a/tools/zipalign/README.txt +++ b/tools/zipalign/README.txt @@ -6,6 +6,7 @@ usage: zipalign [-f] [-v] infile.zip outfile.zip -c : check alignment only (does not modify file) -f : overwrite existing outfile.zip -p : page align stored shared object files + -t : remove dynamic timestamps -v : verbose output is in bytes, e.g. "4" provides 32-bit alignment infile.zip is an existing Zip archive @@ -38,3 +39,5 @@ The "-p" flag aligns any file with a ".so" extension, and which is stored uncompressed in the zip archive, to a 4096-byte page boundary. This facilitates directly loading shared libraries from inside a zip archive. +The "-t" flag removes all timestamps that could change from the archive. + diff --git a/tools/zipalign/ZipAlign.cpp b/tools/zipalign/ZipAlign.cpp index a2dfd0289..2c81a0388 100644 --- a/tools/zipalign/ZipAlign.cpp +++ b/tools/zipalign/ZipAlign.cpp @@ -39,6 +39,7 @@ void usage(void) fprintf(stderr, " -c: check alignment only (does not modify file)\n"); fprintf(stderr, " -f: overwrite existing outfile.zip\n"); fprintf(stderr, " -p: page align stored shared object files\n"); + fprintf(stderr, " -t: remove dynamic timestamps\n"); fprintf(stderr, " -v: verbose output\n"); fprintf(stderr, " -z: recompress using Zopfli\n"); } @@ -64,7 +65,7 @@ static int getAlignment(bool pageAlignSharedLibs, int defaultAlignment, * Copy all entries from "pZin" to "pZout", aligning as needed. */ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfli, - bool pageAlignSharedLibs) + bool pageAlignSharedLibs, bool removeTime) { int numEntries = pZin->getNumEntries(); ZipEntry* pEntry; @@ -88,10 +89,10 @@ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfl // (long) pEntry->getUncompressedLen()); if (zopfli) { - status = pZout->addRecompress(pZin, pEntry, &pNewEntry); + status = pZout->addRecompress(pZin, pEntry, removeTime, &pNewEntry); bias += pNewEntry->getCompressedLen() - pEntry->getCompressedLen(); } else { - status = pZout->add(pZin, pEntry, padding, &pNewEntry); + status = pZout->add(pZin, pEntry, padding, removeTime, &pNewEntry); } } else { const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry); @@ -107,7 +108,7 @@ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfl //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n", // pEntry->getFileName(), (long) pEntry->getFileOffset(), // bias, (long) pEntry->getUncompressedLen(), padding); - status = pZout->add(pZin, pEntry, padding, &pNewEntry); + status = pZout->add(pZin, pEntry, padding, removeTime, &pNewEntry); } if (status != NO_ERROR) @@ -126,7 +127,8 @@ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfl * output file exists and "force" wasn't specified. */ static int process(const char* inFileName, const char* outFileName, - int alignment, bool force, bool zopfli, bool pageAlignSharedLibs) + int alignment, bool force, bool zopfli, bool pageAlignSharedLibs, + bool removeTime) { ZipFile zin, zout; @@ -157,7 +159,7 @@ static int process(const char* inFileName, const char* outFileName, return 1; } - int result = copyAndAlign(&zin, &zout, alignment, zopfli, pageAlignSharedLibs); + int result = copyAndAlign(&zin, &zout, alignment, zopfli, pageAlignSharedLibs, removeTime); if (result != 0) { printf("zipalign: failed rewriting '%s' to '%s'\n", inFileName, outFileName); @@ -228,6 +230,7 @@ int main(int argc, char* const argv[]) bool verbose = false; bool zopfli = false; bool pageAlignSharedLibs = false; + bool removeTime = false; int result = 1; int alignment; char* endp; @@ -260,6 +263,9 @@ int main(int argc, char* const argv[]) case 'p': pageAlignSharedLibs = true; break; + case 't': + removeTime = true; + break; default: fprintf(stderr, "ERROR: unknown flag -%c\n", *cp); wantUsage = true; @@ -290,7 +296,7 @@ int main(int argc, char* const argv[]) result = verify(argv[1], alignment, verbose, pageAlignSharedLibs); } else { /* create the new archive */ - result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs); + result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs, removeTime); /* trust, but verify */ if (result == 0) { diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp index b2270cb0b..934745104 100644 --- a/tools/zipalign/ZipEntry.cpp +++ b/tools/zipalign/ZipEntry.cpp @@ -386,6 +386,14 @@ void ZipEntry::setModWhen(time_t when) mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate; } +/* + * Set static timestamps + */ +void ZipEntry::removeTimestamps() +{ + mCDE.mLastModFileTime = mLFH.mLastModFileTime = 0; + mCDE.mLastModFileDate = mLFH.mLastModFileDate = 28 << 9 | 1 << 5 | 1; +} /* * =========================================================================== diff --git a/tools/zipalign/ZipEntry.h b/tools/zipalign/ZipEntry.h index 7f721b463..0acd05162 100644 --- a/tools/zipalign/ZipEntry.h +++ b/tools/zipalign/ZipEntry.h @@ -185,6 +185,12 @@ protected: */ void setModWhen(time_t when); + /* + * Set a static modification date. This only affects the standard + * zip modification date, not the universal time extra field. + */ + void removeTimestamps(); + /* * Return the offset of the local file header. */ diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp index 3c5ec155b..0ca4d0dcb 100644 --- a/tools/zipalign/ZipFile.cpp +++ b/tools/zipalign/ZipFile.cpp @@ -359,7 +359,7 @@ bail: */ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, const char* storageName, int sourceType, int compressionMethod, - ZipEntry** ppEntry) + bool removeTime, ZipEntry** ppEntry) { ZipEntry* pEntry = NULL; status_t result = NO_ERROR; @@ -499,8 +499,12 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, */ pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc, compressionMethod); - modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp)); - pEntry->setModWhen(modWhen); + if (removeTime) { + pEntry->removeTimestamps(); + } else { + modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp)); + pEntry->setModWhen(modWhen); + } pEntry->setLFHOffset(lfhPosn); mEOCD.mNumEntries++; mEOCD.mTotalNumEntries++; @@ -539,7 +543,7 @@ bail: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - int padding, ZipEntry** ppEntry) + int padding, bool removeTime, ZipEntry** ppEntry) { ZipEntry* pEntry = NULL; status_t result; @@ -571,6 +575,8 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, if (result != NO_ERROR) goto bail; } + if (removeTime) + pEntry->removeTimestamps(); /* * From here on out, failures are more interesting. @@ -646,7 +652,7 @@ bail: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - ZipEntry** ppEntry) + bool removeTime, ZipEntry** ppEntry) { ZipEntry* pEntry = NULL; status_t result; @@ -674,6 +680,9 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour if (result != NO_ERROR) goto bail; + if (removeTime) + pEntry->removeTimestamps(); + /* * From here on out, failures are more interesting. */ diff --git a/tools/zipalign/ZipFile.h b/tools/zipalign/ZipFile.h index b99cda594..787576fc4 100644 --- a/tools/zipalign/ZipFile.h +++ b/tools/zipalign/ZipFile.h @@ -77,17 +77,17 @@ public: * * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ - status_t add(const char* fileName, int compressionMethod, + status_t add(const char* fileName, int compressionMethod, bool removeTime, ZipEntry** ppEntry) { - return add(fileName, fileName, compressionMethod, ppEntry); + return add(fileName, fileName, compressionMethod, removeTime, ppEntry); } status_t add(const char* fileName, const char* storageName, - int compressionMethod, ZipEntry** ppEntry) + int compressionMethod, bool removeTime, ZipEntry** ppEntry) { return addCommon(fileName, NULL, 0, storageName, ZipEntry::kCompressStored, - compressionMethod, ppEntry); + compressionMethod, removeTime, ppEntry); } /* @@ -96,11 +96,12 @@ public: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t addGzip(const char* fileName, const char* storageName, - ZipEntry** ppEntry) + bool removeTime, ZipEntry** ppEntry) { return addCommon(fileName, NULL, 0, storageName, ZipEntry::kCompressDeflated, - ZipEntry::kCompressDeflated, ppEntry); + ZipEntry::kCompressDeflated, + removeTime, ppEntry); } /* @@ -109,11 +110,11 @@ public: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t add(const void* data, size_t size, const char* storageName, - int compressionMethod, ZipEntry** ppEntry) + int compressionMethod, bool removeTime, ZipEntry** ppEntry) { return addCommon(NULL, data, size, storageName, ZipEntry::kCompressStored, - compressionMethod, ppEntry); + compressionMethod, removeTime, ppEntry); } /* @@ -124,7 +125,7 @@ public: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - int padding, ZipEntry** ppEntry); + int padding, bool removeTime, ZipEntry** ppEntry); /* * Add an entry by copying it from another zip file, recompressing with @@ -133,7 +134,7 @@ public: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - ZipEntry** ppEntry); + bool removeTime, ZipEntry** ppEntry); /* * Mark an entry as having been removed. It is not actually deleted @@ -232,7 +233,7 @@ private: /* common handler for all "add" functions */ status_t addCommon(const char* fileName, const void* data, size_t size, const char* storageName, int sourceType, int compressionMethod, - ZipEntry** ppEntry); + bool removeTime, ZipEntry** ppEntry); /* copy all of "srcFp" into "dstFp" */ status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);