summaryrefslogtreecommitdiff
path: root/src/main/java/com
diff options
context:
space:
mode:
authorPaulo Casanova <pasc@google.com>2017-08-03 15:25:00 +0100
committerPaulo Casanova <pasc@google.com>2017-08-11 22:13:30 +0000
commit1ce31f55224a93b1cfca6732ed5b015ecd143514 (patch)
treed90fff32973eef4e2c55fd467a2673098fe401a9 /src/main/java/com
parent7d395b86ccfae70cceb793fde97dc8ec11f33b52 (diff)
downloadapkzlib-1ce31f55224a93b1cfca6732ed5b015ecd143514.tar.gz
Fix alignment when merging zips.
When merging a zip into an apk, apkzlib used to copy all the non-ignored files from the zip as-is. This was done to improve performance as it avoid recompressing files that were already compressed. However, if the files need to be uncompressed (for example, native libraries in M+ devices), this would not ensure that the libraries were uncompressed: if the libraries were compressed in the original zip file, they were copied as-is, i.e., compressed, to the apk breaking alignment. This CL fixes this by ensuring that files that *need* to be uncompressed (and only those) are actually added to the apk following compression and alignment rules. Test: included Bug: http://b/37926537 Change-Id: I69848b37ef33b4f0af07dde8c778c7823443d55b
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/android/apkzlib/zfile/ApkZFileCreator.java25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/main/java/com/android/apkzlib/zfile/ApkZFileCreator.java b/src/main/java/com/android/apkzlib/zfile/ApkZFileCreator.java
index e56f99b..c85ad44 100644
--- a/src/main/java/com/android/apkzlib/zfile/ApkZFileCreator.java
+++ b/src/main/java/com/android/apkzlib/zfile/ApkZFileCreator.java
@@ -26,6 +26,7 @@ import com.google.common.io.Closer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
@@ -114,14 +115,30 @@ class ApkZFileCreator implements ApkCreator {
try {
ZFile toMerge = closer.register(new ZFile(zip));
- Predicate<String> predicate;
+ Predicate<String> ignorePredicate;
if (isIgnored == null) {
- predicate = s -> false;
+ ignorePredicate = s -> false;
} else {
- predicate = isIgnored;
+ ignorePredicate = isIgnored;
}
- this.zip.mergeFrom(toMerge, predicate);
+ // Files that *must* be uncompressed in the result should not be merged and should be
+ // added after. This is just very slightly less efficient than ignoring just the ones
+ // that were compressed and must be uncompressed, but it is a lot simpler :)
+ Predicate<String> noMergePredicate = ignorePredicate.or(noCompressPredicate);
+
+ this.zip.mergeFrom(toMerge, noMergePredicate);
+
+ for (StoredEntry toMergeEntry : toMerge.entries()) {
+ String path = toMergeEntry.getCentralDirectoryHeader().getName();
+ if (noCompressPredicate.test(path) && !ignorePredicate.test(path)) {
+ // This entry *must* be uncompressed so it was ignored in the merge and should
+ // now be added to the apk.
+ try (InputStream ignoredData = toMergeEntry.open()) {
+ this.zip.add(path, ignoredData, false);
+ }
+ }
+ }
} catch (Throwable t) {
throw closer.rethrow(t);
} finally {