Merge pull request #2000 from vbarthel-fr/issue-1994

fix: issue 1994
This commit is contained in:
Connor Tumbleson 2019-01-30 10:04:58 -05:00 committed by GitHub
commit 43c3b9644c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 7 deletions

2
.gitignore vendored
View File

@ -20,7 +20,7 @@ bin/
# IntelliJ # IntelliJ
*.iml *.iml
.idea/* .idea/*
/out **/out/
# Patches # Patches
*.patch *.patch

View File

@ -24,6 +24,11 @@ import java.util.*;
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public final class ResTypeSpec { 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 String mName;
private final Map<String, ResResSpec> mResSpecs = new LinkedHashMap<String, ResResSpec>(); private final Map<String, ResResSpec> mResSpecs = new LinkedHashMap<String, ResResSpec>();

View File

@ -19,6 +19,7 @@ package brut.androlib.res.data.value;
import android.util.TypedValue; import android.util.TypedValue;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResPackage; import brut.androlib.res.data.ResPackage;
import brut.androlib.res.data.ResTypeSpec;
import brut.util.Duo; import brut.util.Duo;
/** /**
@ -83,7 +84,7 @@ public class ResValueFactory {
return new ResStringValue(value, rawValue); return new ResStringValue(value, rawValue);
} }
public ResBagValue bagFactory(int parent, Duo<Integer, ResScalarValue>[] items) throws AndrolibException { public ResBagValue bagFactory(int parent, Duo<Integer, ResScalarValue>[] items, ResTypeSpec resTypeSpec) throws AndrolibException {
ResReferenceValue parentVal = newReference(parent, null); ResReferenceValue parentVal = newReference(parent, null);
if (items.length == 0) { if (items.length == 0) {
@ -93,14 +94,25 @@ public class ResValueFactory {
if (key == ResAttr.BAG_KEY_ATTR_TYPE) { if (key == ResAttr.BAG_KEY_ATTR_TYPE) {
return ResAttr.factory(parentVal, items, this, mPackage); 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); 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 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) { public ResReferenceValue newReference(int resID, String rawValue) {

View File

@ -347,7 +347,7 @@ public class ARSCDecoder {
} }
} }
return factory.bagFactory(parent, items); return factory.bagFactory(parent, items, mTypeSpec);
} }
private ResIntBasedValue readValue() throws IOException, AndrolibException { private ResIntBasedValue readValue() throws IOException, AndrolibException {

View File

@ -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);
}
}