diff --git a/.gitignore b/.gitignore index fe7ff60a..07176cc0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ bin/ # IntelliJ *.iml .idea/* -/out +**/out/ # Patches *.patch \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java index 0c2de96d..df07f7c8 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java @@ -24,6 +24,11 @@ import java.util.*; * @author Ryszard Wiśniewski */ public final class ResTypeSpec { + + public static final String RES_TYPE_NAME_ARRAY = "array"; + public static final String RES_TYPE_NAME_PLURALS = "plurals"; + public static final String RES_TYPE_NAME_STYLES = "style"; + private final String mName; private final Map mResSpecs = new LinkedHashMap(); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java index ee21befd..fae59dbc 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java @@ -19,6 +19,7 @@ package brut.androlib.res.data.value; import android.util.TypedValue; import brut.androlib.AndrolibException; import brut.androlib.res.data.ResPackage; +import brut.androlib.res.data.ResTypeSpec; import brut.util.Duo; /** @@ -83,7 +84,7 @@ public class ResValueFactory { return new ResStringValue(value, rawValue); } - public ResBagValue bagFactory(int parent, Duo[] items) throws AndrolibException { + public ResBagValue bagFactory(int parent, Duo[] items, ResTypeSpec resTypeSpec) throws AndrolibException { ResReferenceValue parentVal = newReference(parent, null); if (items.length == 0) { @@ -93,14 +94,25 @@ public class ResValueFactory { if (key == ResAttr.BAG_KEY_ATTR_TYPE) { return ResAttr.factory(parentVal, items, this, mPackage); } - // Android O Preview added an unknown enum for ResTable_map. This is hardcoded as 0 for now. - if (key == ResArrayValue.BAG_KEY_ARRAY_START || key == 0) { + + String resTypeName = resTypeSpec.getName(); + + // Android O Preview added an unknown enum for c. This is hardcoded as 0 for now. + if (ResTypeSpec.RES_TYPE_NAME_ARRAY.equals(resTypeName) + || key == ResArrayValue.BAG_KEY_ARRAY_START || key == 0) { return new ResArrayValue(parentVal, items); } - if (key >= ResPluralsValue.BAG_KEY_PLURALS_START && key <= ResPluralsValue.BAG_KEY_PLURALS_END) { + + if (ResTypeSpec.RES_TYPE_NAME_PLURALS.equals(resTypeName) || + (key >= ResPluralsValue.BAG_KEY_PLURALS_START && key <= ResPluralsValue.BAG_KEY_PLURALS_END)) { return new ResPluralsValue(parentVal, items); } - return new ResStyleValue(parentVal, items, this); + + if (ResTypeSpec.RES_TYPE_NAME_STYLES.equals(resTypeName)) { + return new ResStyleValue(parentVal, items, this); + } + + throw new AndrolibException("unsupported res type name for bags. Found: " + resTypeName); } public ResReferenceValue newReference(int resID, String rawValue) { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index 290a6615..86efecff 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -347,7 +347,7 @@ public class ARSCDecoder { } } - return factory.bagFactory(parent, items); + return factory.bagFactory(parent, items, mTypeSpec); } private ResIntBasedValue readValue() throws IOException, AndrolibException { diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java new file mode 100644 index 00000000..c2bdf5e4 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java @@ -0,0 +1,55 @@ +package brut.androlib.decode; + +import brut.androlib.ApkDecoder; +import brut.androlib.BaseTest; +import brut.androlib.TestUtils; +import brut.androlib.res.data.ResTable; +import brut.androlib.res.data.value.ResArrayValue; +import brut.androlib.res.data.value.ResValue; +import brut.common.BrutException; +import brut.directory.ExtFile; +import brut.util.OS; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; + +import static junit.framework.Assert.assertTrue; + +public class DecodeArrayTest extends BaseTest { + + @BeforeClass + public static void beforeClass() throws Exception { + TestUtils.cleanFrameworkFile(); + sTmpDir = new ExtFile(OS.createTempDirectory()); + TestUtils.copyResourceDir(MissingVersionManifestTest.class, "decode/issue1994/", sTmpDir); + } + + @AfterClass + public static void afterClass() throws BrutException { + OS.rmdir(sTmpDir); + } + + @Test + public void decodeStringArray() throws BrutException { + String apk = "issue1994.apk"; + ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + apk)); + + ResTable resTable = apkDecoder.getResTable(); + ResValue value = resTable.getResSpec(0x7f020001).getDefaultResource().getValue(); + + assertTrue("Not a ResArrayValue. Found: " + value.getClass(), value instanceof ResArrayValue); + } + + @Test + public void decodeArray() throws BrutException { + String apk = "issue1994.apk"; + ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + apk)); + + ResTable resTable = apkDecoder.getResTable(); + ResValue value = resTable.getResSpec(0x7f020000).getDefaultResource().getValue(); + + assertTrue("Not a ResArrayValue. Found: " + value.getClass(), value instanceof ResArrayValue); + } +} diff --git a/brut.apktool/apktool-lib/src/test/resources/decode/issue1994/issue1994.apk b/brut.apktool/apktool-lib/src/test/resources/decode/issue1994/issue1994.apk new file mode 100644 index 00000000..2443f683 Binary files /dev/null and b/brut.apktool/apktool-lib/src/test/resources/decode/issue1994/issue1994.apk differ