summaryrefslogtreecommitdiff
path: root/tools/zipalign/ZipFile.cpp
diff options
context:
space:
mode:
author Fabien Sanglard <sanglardf@google.com> 2020-10-20 15:47:10 -0700
committer Fabien Sanglard <sanglardf@google.com> 2020-11-11 17:00:22 -0800
commita720635be20f4fc3acd39c7b83b919140ced0f94 (patch)
treeffc517c792221d56f4f8fd0b6066a9fb3e4f5cb1 /tools/zipalign/ZipFile.cpp
parent6f83343e7eae8fd826770009cabe1827754152f7 (diff)
Fix zipalign alignment error
Problem: Zipalign operates over several false assumptions. First it assumes that zip entries are in the same order in the body and in the Central Direcotry. Second, it assumes there are not space between entries. This makes alignment incorrect when these asserts are not true. Solution: Don't align entries by tracking bias based on input zip entry location. Calculate the expected alignment based on the out- put zip file and correct with extra padding. Fixes: 162117652 Test: Units Tests Change-Id: Ia179338f658cab18a377cba2c7c8e629089a2785
Diffstat (limited to 'tools/zipalign/ZipFile.cpp')
-rw-r--r--tools/zipalign/ZipFile.cpp37
1 files changed, 31 insertions, 6 deletions
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 29d1bc6849..9938a06088 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -503,6 +503,32 @@ bail:
}
/*
+ * Based on the current position in the output zip, assess where the entry
+ * payload will end up if written as-is. If alignment is not satisfactory,
+ * add some padding in the extra field.
+ *
+ */
+status_t ZipFile::alignEntry(android::ZipEntry* pEntry, uint32_t alignTo){
+ if (alignTo == 0 || alignTo == 1)
+ return OK;
+
+ // Calculate where the entry payload offset will end up if we were to write
+ // it as-is.
+ uint64_t expectedPayloadOffset = ftell(mZipFp) +
+ android::ZipEntry::LocalFileHeader::kLFHLen +
+ pEntry->mLFH.mFileNameLength +
+ pEntry->mLFH.mExtraFieldLength;
+
+ // If the alignment is not what was requested, add some padding in the extra
+ // so the payload ends up where is requested.
+ uint64_t alignDiff = alignTo - (expectedPayloadOffset % alignTo);
+ if (alignDiff == 0)
+ return OK;
+
+ return pEntry->addPadding(alignDiff);
+}
+
+/*
* Add an entry by copying it from another zip file. If "padding" is
* nonzero, the specified number of bytes will be added to the "extra"
* field in the header.
@@ -510,7 +536,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 alignTo, ZipEntry** ppEntry)
{
ZipEntry* pEntry = NULL;
status_t result;
@@ -537,11 +563,10 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
result = pEntry->initFromExternal(pSourceEntry);
if (result != OK)
goto bail;
- if (padding != 0) {
- result = pEntry->addPadding(padding);
- if (result != OK)
- goto bail;
- }
+
+ result = alignEntry(pEntry, alignTo);
+ if (result != OK)
+ goto bail;
/*
* From here on out, failures are more interesting.