Skip to content

Commit d294111

Browse files
authored
fix: decoding references to private resources (#2650)
* fix: decoding references to private resources * style: fix naming in constructor parameter * test: add test to check build/decode private references
1 parent 9bdf385 commit d294111

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import brut.androlib.AndrolibException;
2020
import brut.androlib.err.UndefinedResObjectException;
21+
import brut.androlib.res.decoder.ARSCDecoder;
2122
import org.apache.commons.lang3.StringUtils;
2223

2324
import java.util.LinkedHashMap;
@@ -28,11 +29,13 @@
2829
public class ResResSpec {
2930
private final ResID mId;
3031
private final String mName;
32+
private final int mFlags;
3133
private final ResPackage mPackage;
3234
private final ResTypeSpec mType;
3335
private final Map<ResConfigFlags, ResResource> mResources = new LinkedHashMap<>();
3436

35-
public ResResSpec(ResID id, String name, ResPackage pkg, ResTypeSpec type) {
37+
public ResResSpec(ResID id, String name, int flags, ResPackage pkg, ResTypeSpec type) {
38+
this.mFlags = flags;
3639
this.mId = id;
3740
String cleanName;
3841

@@ -72,13 +75,19 @@ public boolean hasDefaultResource() {
7275
return mResources.containsKey(new ResConfigFlags());
7376
}
7477

78+
public boolean isPublicResource() {
79+
return (getFlags() & ARSCDecoder.ENTRY_FLAG_PUBLIC) != 0;
80+
}
81+
7582
public String getFullName(ResPackage relativeToPackage, boolean excludeType) {
7683
return getFullName(getPackage().equals(relativeToPackage), excludeType);
7784
}
7885

7986
public String getFullName(boolean excludePackage, boolean excludeType) {
80-
return (excludePackage ? "" : getPackage().getName() + ":")
81-
+ (excludeType ? "" : getType().getName() + "/") + getName();
87+
String privateSuffix = isPublicResource() ? "" : "*";
88+
String packageName = excludePackage ? "" : getPackage().getName() + ":";
89+
return (packageName.isEmpty() ? "" : privateSuffix + packageName)
90+
+ (excludeType ? "" : getType().getName() + "/") + getName();
8291
}
8392

8493
public ResID getId() {
@@ -97,6 +106,10 @@ public ResTypeSpec getType() {
97106
return mType;
98107
}
99108

109+
public int getFlags() {
110+
return mFlags;
111+
}
112+
100113
public boolean isDummyResSpec() {
101114
return getName().startsWith("APKTOOL_DUMMY_");
102115
}

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,12 @@ private void readEntry(EntryData entryData) throws AndrolibException {
309309
if (spec.isDummyResSpec()) {
310310
removeResSpec(spec);
311311

312-
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mTypeSpec);
312+
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), entryData.mFlags, mPkg, mTypeSpec);
313313
mPkg.addResSpec(spec);
314314
mTypeSpec.addResSpec(spec);
315315
}
316316
} else {
317-
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mTypeSpec);
317+
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), entryData.mFlags, mPkg, mTypeSpec);
318318
mPkg.addResSpec(spec);
319319
mTypeSpec.addResSpec(spec);
320320
}
@@ -511,7 +511,7 @@ private void addMissingResSpecs() throws AndrolibException {
511511
continue;
512512
}
513513

514-
ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), mPkg, mTypeSpec);
514+
ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), ENTRY_FLAG_PUBLIC, mPkg, mTypeSpec);
515515

516516
// If we already have this resID dont add it again.
517517
if (! mPkg.hasResSpec(new ResID(resId | i))) {
@@ -575,7 +575,7 @@ private void nextChunkCheckType(int expectedType) throws IOException, AndrolibEx
575575
private final HashMap<Integer, ResTypeSpec> mResTypeSpecs = new HashMap<>();
576576

577577
private final static short ENTRY_FLAG_COMPLEX = 0x0001;
578-
private final static short ENTRY_FLAG_PUBLIC = 0x0002;
578+
public final static short ENTRY_FLAG_PUBLIC = 0x0002;
579579
private final static short ENTRY_FLAG_WEAK = 0x0004;
580580

581581
public static class Header {

brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/BuildAndDecodeTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ public void valuesStringsTest() throws BrutException {
7272
compareValuesFiles("values/strings.xml");
7373
}
7474

75+
@Test
76+
public void valuesColorsTest() throws BrutException {
77+
compareValuesFiles("values/colors.xml");
78+
}
79+
80+
@Test
81+
public void valuesBoolsTest() throws BrutException {
82+
compareValuesFiles("values/bools.xml");
83+
}
84+
7585
@Test
7686
public void valuesMaxLengthTest() throws BrutException {
7787
compareValuesFiles("values-es/strings.xml");
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<item type="bool" name="bool_private_reference">@*android:bool/config_enableActivityRecognitionHardwareOverlay</item>
4+
</resources>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<color name="color_private_reference">@*android:color/Indigo_700</color>
4+
</resources>

0 commit comments

Comments
 (0)