From f82b2e1855ddcc7beb40e19eb8a9c71f13c622b2 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 13 Jan 2013 08:19:42 -0600 Subject: [PATCH] fixes issue #67 - only compresses resources.arsc if original apk had compressoin --- .../src/main/java/brut/apktool/Main.java | 5 +++ .../src/main/java/brut/androlib/Androlib.java | 1 + .../main/java/brut/androlib/ApkDecoder.java | 43 ++++++++++++++++++- .../brut/androlib/res/AndrolibResources.java | 7 ++- .../brut/androlib/BuildAndDecodeTest.java | 2 +- 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java index 8b9505ea..649506c3 100644 --- a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java +++ b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java @@ -155,7 +155,12 @@ public class Main { String.valueOf(ex.getPkgId()) + ". You must install proper " + "framework files, see project website for more info."); System.exit(1); + } catch (IOException ex) { + System.out.println( + "Could not modify file. Please ensure you have permission."); + System.exit(1); } + } private static void cmdBuild(String[] args) throws BrutException { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java index 5465733e..6a2e7441 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java @@ -183,6 +183,7 @@ public class Androlib { Map meta = readMetaFile(appDir); Object t1 = meta.get("isFrameworkApk"); flags.put("framework", t1 == null ? false : (Boolean) t1); + flags.put("compression", meta.get("compressionType") == null ? false : (Boolean) meta.get("compressionType")); mAndRes.setSdkInfo((Map) meta.get("sdkInfo")); // check the orig apk diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java index 9b6099d5..e1ed91e8 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java @@ -26,7 +26,11 @@ import brut.common.BrutException; import brut.directory.DirectoryException; import brut.util.OS; import java.io.File; +import java.io.IOException; import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; /** * @author Ryszard Wiśniewski @@ -58,7 +62,7 @@ public class ApkDecoder { mOutDir = outDir; } - public void decode() throws AndrolibException { + public void decode() throws AndrolibException, IOException { File outDir = getOutDir(); if (!mForceDelete && outDir.exists()) { @@ -91,6 +95,20 @@ public class ApkDecoder { } if (hasResources()) { + + // read the resources.arsc checking for STORED vs DEFLATE compression + // this will determine whether we compress on rebuild or not. + JarFile jf = new JarFile(mApkFile.getAbsoluteFile()); + Enumeration e = jf.entries(); + while(e.hasMoreElements()) { + JarEntry je = (JarEntry) e.nextElement(); + if (je.getName().equalsIgnoreCase("resources.arsc")) { + setCompressionType(je.getMethod()); + continue; + } + } + jf.close(); + switch (mDecodeResources) { case DECODE_RESOURCES_NONE: mAndrolib.decodeResourcesRaw(mApkFile, outDir); @@ -227,6 +245,7 @@ public class ApkDecoder { putUsesFramework(meta); putSdkInfo(meta); putPackageInfo(meta); + putCompressionInfo(meta); } mAndrolib.writeMetaFile(mOutDir, meta); @@ -270,6 +289,27 @@ public class ApkDecoder { meta.put("packageInfo", info); } } + + private void putCompressionInfo(Map meta) + throws AndrolibException { + meta.put("compressionType", getCompressionType()); + } + + private boolean getCompressionType() { + return mCompressResources; + } + + private void setCompressionType(int compression) { + + // check for deflate vs stored + if (compression == ZipEntry.STORED) { + mCompressResources = false; + } else if (compression == ZipEntry.DEFLATED) { + mCompressResources = true; + } else { + mCompressResources = false; + } + } private final Androlib mAndrolib; @@ -284,4 +324,5 @@ public class ApkDecoder { private boolean mKeepBrokenResources = false; private String mFrameworkDir = null; private boolean mBakDeb = true; + private boolean mCompressResources = false; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index e8a02c83..a3b66a8a 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -320,8 +320,11 @@ final public class AndrolibResources { if (flags.get("framework")) { cmd.add("-x"); - // cmd.add("-0"); - // cmd.add("arsc"); + } + + if (!(flags.get("compression"))) { + cmd.add("-0"); + cmd.add("arsc"); } if (include != null) { diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java index de09e674..efa384b6 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java @@ -33,7 +33,7 @@ import org.xml.sax.SAXException; public class BuildAndDecodeTest { @BeforeClass - public static void beforeClass() throws BrutException { + public static void beforeClass() throws BrutException, IOException { sTmpDir = new ExtFile(OS.createTempDirectory()); sTestOrigDir = new ExtFile(sTmpDir, "testapp-orig"); sTestNewDir = new ExtFile(sTmpDir, "testapp-new");