Skip to content

Commit 515af4f

Browse files
authored
Reworks Attr/Array Handler (#3326)
* test: add example pkcs key * fix: rework towards ResScalarValue instead of ResIntValue * fix: prefer res name instead of "guessing" based on ids
1 parent c07e4a9 commit 515af4f

File tree

8 files changed

+40
-48
lines changed

8 files changed

+40
-48
lines changed

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
public final class ResTypeSpec {
2424

2525
public static final String RES_TYPE_NAME_ARRAY = "array";
26+
public static final String RES_TYPE_NAME_ATTR = "attr";
27+
public static final String RES_TYPE_NAME_ATTR_PRIVATE = "^attr-private";
2628
public static final String RES_TYPE_NAME_PLURALS = "plurals";
29+
public static final String RES_TYPE_NAME_STRING = "string";
2730
public static final String RES_TYPE_NAME_STYLES = "style";
28-
public static final String RES_TYPE_NAME_ATTR = "attr";
2931

3032
private final String mName;
3133
private final Map<String, ResResSpec> mResSpecs = new LinkedHashMap<>();
@@ -46,7 +48,7 @@ public int getId() {
4648
}
4749

4850
public boolean isString() {
49-
return mName.equalsIgnoreCase("string");
51+
return mName.equalsIgnoreCase(RES_TYPE_NAME_STRING);
5052
}
5153

5254
public ResResSpec getResSpec(String name) throws AndrolibException {

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,4 @@ public String getType() throws AndrolibException {
9191

9292
private final ResScalarValue[] mItems;
9393
private final String[] AllowedArrayTypes = {"string", "integer"};
94-
95-
public static final int BAG_KEY_ARRAY_START = 0x02000000;
9694
}

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,38 +64,39 @@ public void serializeToResValuesXml(XmlSerializer serializer, ResResource res) t
6464
public static ResAttr factory(ResReferenceValue parent,
6565
Duo<Integer, ResScalarValue>[] items, ResValueFactory factory,
6666
ResPackage pkg) throws AndrolibException {
67-
68-
int type = ((ResIntValue) items[0].m2).getValue();
69-
int scalarType = type & 0xffff;
7067
Integer min = null, max = null;
7168
Boolean l10n = null;
7269
int i;
7370
for (i = 1; i < items.length; i++) {
7471
switch (items[i].m1) {
7572
case BAG_KEY_ATTR_MIN:
76-
min = ((ResIntValue) items[i].m2).getValue();
73+
min = (items[i].m2).getRawIntValue();
7774
continue;
7875
case BAG_KEY_ATTR_MAX:
79-
max = ((ResIntValue) items[i].m2).getValue();
76+
max = (items[i].m2).getRawIntValue();
8077
continue;
8178
case BAG_KEY_ATTR_L10N:
82-
l10n = ((ResIntValue) items[i].m2).getValue() != 0;
79+
l10n = (items[i].m2).getRawIntValue() != 0;
8380
continue;
8481
}
8582
break;
8683
}
8784

85+
// #2806 - Make sure we handle int-based values and not just ResIntValue
86+
int rawValue = items[0].m2.getRawIntValue();
87+
int scalarType = rawValue & 0xffff;
88+
8889
if (i == items.length) {
8990
return new ResAttr(parent, scalarType, min, max, l10n);
9091
}
91-
Duo<ResReferenceValue, ResIntValue>[] attrItems = new Duo[items.length - i];
92+
Duo<ResReferenceValue, ResScalarValue>[] attrItems = new Duo[items.length - i];
9293
int j = 0;
9394
for (; i < items.length; i++) {
9495
int resId = items[i].m1;
9596
pkg.addSynthesizedRes(resId);
96-
attrItems[j++] = new Duo<>(factory.newReference(resId, null), (ResIntValue) items[i].m2);
97+
attrItems[j++] = new Duo<>(factory.newReference(resId, null), items[i].m2);
9798
}
98-
switch (type & 0xff0000) {
99+
switch (rawValue & 0xff0000) {
99100
case TYPE_ENUM:
100101
return new ResEnumAttr(parent, scalarType, min, max, l10n, attrItems);
101102
case TYPE_FLAGS:
@@ -145,7 +146,6 @@ protected String getTypeAsString() {
145146
private final Integer mMax;
146147
private final Boolean mL10n;
147148

148-
public static final int BAG_KEY_ATTR_TYPE = 0x01000000;
149149
private static final int BAG_KEY_ATTR_MIN = 0x01000001;
150150
private static final int BAG_KEY_ATTR_MAX = 0x01000002;
151151
private static final int BAG_KEY_ATTR_L10N = 0x01000003;

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
public class ResEnumAttr extends ResAttr {
3131
ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max,
32-
Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
32+
Boolean l10n, Duo<ResReferenceValue, ResScalarValue>[] items) {
3333
super(parent, type, min, max, l10n);
3434
mItems = items;
3535
}
@@ -48,8 +48,8 @@ public String convertToResXmlFormat(ResScalarValue value)
4848

4949
@Override
5050
protected void serializeBody(XmlSerializer serializer, ResResource res) throws AndrolibException, IOException {
51-
for (Duo<ResReferenceValue, ResIntValue> duo : mItems) {
52-
int intVal = duo.m2.getValue();
51+
for (Duo<ResReferenceValue, ResScalarValue> duo : mItems) {
52+
int intVal = duo.m2.getRawIntValue();
5353

5454
// #2836 - Support skipping items if the resource cannot be identified.
5555
ResResSpec m1Referent = duo.m1.getReferent();
@@ -72,8 +72,8 @@ private String decodeValue(int value) throws AndrolibException {
7272
String value2 = mItemsCache.get(value);
7373
if (value2 == null) {
7474
ResReferenceValue ref = null;
75-
for (Duo<ResReferenceValue, ResIntValue> duo : mItems) {
76-
if (duo.m2.getValue() == value) {
75+
for (Duo<ResReferenceValue, ResScalarValue> duo : mItems) {
76+
if (duo.m2.getRawIntValue() == value) {
7777
ref = duo.m1;
7878
break;
7979
}
@@ -86,7 +86,7 @@ private String decodeValue(int value) throws AndrolibException {
8686
return value2;
8787
}
8888

89-
private final Duo<ResReferenceValue, ResIntValue>[] mItems;
89+
private final Duo<ResReferenceValue, ResScalarValue>[] mItems;
9090
private final Map<Integer, String> mItemsCache = new HashMap<>();
9191

9292
private static final Logger LOGGER = Logger.getLogger(ResEnumAttr.class.getName());

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929

3030
public class ResFlagsAttr extends ResAttr {
3131
ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max,
32-
Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
32+
Boolean l10n, Duo<ResReferenceValue, ResScalarValue>[] items) {
3333
super(parent, type, min, max, l10n);
3434

3535
mItems = new FlagItem[items.length];
3636
for (int i = 0; i < items.length; i++) {
37-
mItems[i] = new FlagItem(items[i].m1, items[i].m2.getValue());
37+
mItems[i] = new FlagItem(items[i].m1, items[i].m2.getRawIntValue());
3838
}
3939
}
4040

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,5 @@ public void serializeToResValuesXml(XmlSerializer serializer,
5959
private final ResScalarValue[] mItems;
6060

6161
public static final int BAG_KEY_PLURALS_START = 0x01000004;
62-
public static final int BAG_KEY_PLURALS_END = 0x01000009;
6362
private static final String[] QUANTITY_MAP = new String[] { "other", "zero", "one", "two", "few", "many" };
6463
}

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -80,39 +80,29 @@ public ResIntBasedValue factory(String value, int rawValue) {
8080
return new ResStringValue(value, rawValue);
8181
}
8282

83-
public ResBagValue bagFactory(int parent, Duo<Integer, ResScalarValue>[] items, ResTypeSpec resTypeSpec) throws AndrolibException {
83+
public ResBagValue bagFactory(int parent, Duo<Integer, ResScalarValue>[] items, ResTypeSpec resTypeSpec)
84+
throws AndrolibException {
8485
ResReferenceValue parentVal = newReference(parent, null);
8586

8687
if (items.length == 0) {
8788
return new ResBagValue(parentVal);
8889
}
89-
int key = items[0].m1;
90-
if (key == ResAttr.BAG_KEY_ATTR_TYPE) {
91-
return ResAttr.factory(parentVal, items, this, mPackage);
92-
}
93-
9490
String resTypeName = resTypeSpec.getName();
9591

96-
// Android O Preview added an unknown enum for c. This is hardcoded as 0 for now.
97-
if (ResTypeSpec.RES_TYPE_NAME_ARRAY.equals(resTypeName)
98-
|| key == ResArrayValue.BAG_KEY_ARRAY_START || key == 0) {
99-
return new ResArrayValue(parentVal, items);
100-
}
101-
102-
if (ResTypeSpec.RES_TYPE_NAME_PLURALS.equals(resTypeName) ||
103-
(key >= ResPluralsValue.BAG_KEY_PLURALS_START && key <= ResPluralsValue.BAG_KEY_PLURALS_END)) {
104-
return new ResPluralsValue(parentVal, items);
105-
}
106-
107-
if (ResTypeSpec.RES_TYPE_NAME_ATTR.equals(resTypeName)) {
108-
return new ResAttr(parentVal, 0, null, null, null);
109-
}
110-
111-
if (resTypeName.startsWith(ResTypeSpec.RES_TYPE_NAME_STYLES)) {
112-
return new ResStyleValue(parentVal, items, this);
92+
switch (resTypeName) {
93+
case ResTypeSpec.RES_TYPE_NAME_ATTR:
94+
case ResTypeSpec.RES_TYPE_NAME_ATTR_PRIVATE:
95+
return ResAttr.factory(parentVal, items, this, mPackage);
96+
case ResTypeSpec.RES_TYPE_NAME_ARRAY:
97+
return new ResArrayValue(parentVal, items);
98+
case ResTypeSpec.RES_TYPE_NAME_PLURALS:
99+
return new ResPluralsValue(parentVal, items);
100+
default:
101+
if (resTypeName.startsWith(ResTypeSpec.RES_TYPE_NAME_STYLES)) {
102+
return new ResStyleValue(parentVal, items, this);
103+
}
104+
throw new AndrolibException("unsupported res type name for bags. Found: " + resTypeName);
113105
}
114-
115-
throw new AndrolibException("unsupported res type name for bags. Found: " + resTypeName);
116106
}
117107

118108
public ResReferenceValue newReference(int resID, String rawValue) {

brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/res/values-mcc001/arrays.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,7 @@
3535
<item>res/</item>
3636
<item>view/</item>
3737
</string-array>
38+
<string-array name="issue_2806">
39+
<item>MIICXAIBAAKBgQCjcGqTkOq0CR3rTx0ZSQSIdTrDrFAYl29611xN8aVgMQIWtDB/lD0W5TpKPuU9iaiG/sSn/VYt6EzN7Sr332jj7cyl2WrrHI6ujRswNy4HojMuqtfab5FFDpRmCuvl35fge18OvoQTJELhhJ1EvJ5KUeZiuJ3u3YyMnxxXzLuKbQIDAQABAoGAPrNDz7TKtaLBvaIuMaMXgBopHyQd3jFKbT/tg2Fu5kYm3PrnmCoQfZYXFKCoZUFIS/G1FBVWWGpD/MQ9tbYZkKpwuH+t2rGndMnLXiTC296/s9uix7gsjnT4Naci5N6EN9pVUBwQmGrYUTHFc58ThtelSiPARX7LSU2ibtJSv8ECQQDWBRrrAYmbCUN7ra0DFT6SppaDtvvuKtb+mUeKbg0B8U4y4wCIK5GH8EyQSwUWcXnNBO05rlUPbifsDLv/u82lAkEAw39sTJ0KmJJyaChqvqAJ8guulKlgucQJ0Et9ppZyet9iVwNKX/aW9UlwGBMQdafQ36nd1QMEA8AbAw4D+hw/KQJBANJbHDUGQtk2hrSmZNoV5HXB9Uiq7v4N71k5ER8XwgM5yVGs2tX8dMM3RhnBEtQXXs9LW1uJZSOQcv7JGXNnhN0CQBZenzrJAWxh3XtznHtBfsHWelyCYRIAj4rpCHCmaGUM6IjCVKFUawOYKp5mmAyObkUZf8ue87emJLEdynC1CLkCQHduNjP1hemAGWrd6v8BHhE3kKtcK6KHsPvJR5dOfzbdHAqVePERhISfN6cwZt5p8B3/JUwSR8el66DF7Jm57BM=</item>
40+
</string-array>
3841
</resources>

0 commit comments

Comments
 (0)