Apktool
                                
                                
                                
                                    Apktool copied to clipboard
                            
                            
                            
                        [BUG] Chunk [amp] is not a valid entry
Information
- Apktool Version (
apktool -version) - 2.6.0 - Operating System (Mac, Linux, Windows) - win
 - APK From? (Playstore, ROM, Other) - rom
 
Stacktrace/Logcat
I: Using Apktool 2.6.0 on Settings.apk
I: Loading resource table...
I: Decoding Shared Library (miui), pkgId: 16
I: Decoding Shared Library (android.miui), pkgId: 17
I: Decoding Shared Library (miui.system), pkgId: 18
Exception in thread "main" java.lang.IllegalArgumentException: Chunk [amp] is not a valid entry
        at com.google.common.base.Preconditions.checkArgument(Preconditions.java:219)
        at com.google.common.base.Splitter$MapSplitter.split(Splitter.java:526)
        at brut.androlib.res.decoder.StringBlock$Tag.toString(StringBlock.java:167)
        at java.base/java.lang.String.valueOf(String.java:2951)
        at java.base/java.lang.StringBuilder.append(StringBuilder.java:168)
        at brut.androlib.res.decoder.StringBlock.processStyledString(StringBlock.java:260)
        at brut.androlib.res.decoder.StringBlock.getHTML(StringBlock.java:288)
        at brut.androlib.res.decoder.ARSCDecoder.readValue(ARSCDecoder.java:366)
        at brut.androlib.res.decoder.ARSCDecoder.readEntryData(ARSCDecoder.java:285)
        at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:261)
        at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:184)
        at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:135)
        at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:84)
        at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:50)
        at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:783)
        at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:64)
        at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:56)
        at brut.androlib.Androlib.getResTable(Androlib.java:69)
        at brut.androlib.ApkDecoder.getResTable(ApkDecoder.java:247)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:109)
        at brut.apktool.Main.cmdDecode(Main.java:175)
        at brut.apktool.Main.main(Main.java:78)
Steps to Reproduce
java -jar apktool_2.6.0.jar d -p frameworks Settings.apk
APK & Frameworks
https://drive.google.com/file/d/1pHBX9k4_lAhchdXMTJSfeMYiDWklTH94/view?usp=sharing
Issue:
The commit https://github.com/iBotPeaches/Apktool/commit/087142d4cf9cc43f91c9034ee05c9cf020e6b368 messed up the Settings.apk decompilation from the MIUI ROM.
Confirmed. Marking as bug.
@iBotPeaches solution to the problem: ResXmlEncoders.java
public final class ResXmlEncoders {
    public static String escapeXmlChars(String str) {
        return StringUtils.replace(StringUtils.replace(str, "&", "&"), "<", "<");
    }
...
}
to
import org.apache.commons.text.StringEscapeUtils;
public final class ResXmlEncoders {
    public static String escapeXmlChars(String str) {
        str = StringEscapeUtils.unescapeXml(str);
        str = StringUtils.replace(str, "&", "&");
        str = StringUtils.replace(str, "<", "<");
        return str;
    }
...
}
... strings PT-rPT are still not correct, if you remove them, then recompilation occurs normally.
@pashamcr I'm not following how unescaping XML in a function that is called escaping has anything to do with a proper fix here. Can you give some background on to why you believe this works?
Also, Pull Requests are always available :)
@iBotPeaches, I changed the code even further:
import org.unbescape.xml.XmlEscape;
import org.unbescape.html.HtmlEscape;
public final class ResXmlEncoders {
    public static String escapeXmlChars(String str) {
        str = XmlEscape.unescapeXml(str);
        str = HtmlEscape.unescapeHtml(str);
        str = StringUtils.replace(str, "&", "&");
        str = StringUtils.replace(str, "<", "<");
        return str;
    }
I can say for sure that apktool is complaining about amp inside the http address:
aapt2 dump resources Settings.apk > res.txt
Normal string:
      (da) "<Data>For at kunne bruge basisfunktionerne af denne tjeneste, skal du acceptere, at Xiaomi indsamler, bearbejder, og bruger dine personlige data. Se vores fortrolighedspolitik for at finde ud af, hvordan vi indsamler og bearbejder personlige data. Hvis du vælger "Acceptér", betyder det, at du har læst og accepteret vores <a href="https://privacy.mi.com/all/%1$s_%2$s">Fortrolighedspolitik</a> og <a href="http://www.miui.com/res/doc/eula.html?region=%3$s&lang=%4$s">Brugeraftale</a>.</Data>"
Wrong string:
      (de) "<Data>Um grundlegende Funktionen dieses Dienstes nutzen zu können, müssen Sie zustimmen, dass Xiaomi Ihre persönlichen Daten erhebt, verarbeitet und nutzt. In unserer Datenschutzerklärung erfahren Sie, wie wir personenbezogene Daten erheben und verarbeiten. "Zustimmen" wählen bedeutet, dass Sie unsere <a href="https://privacy.mi.com/all/%1$s_%2$s">Datenschutzerklärung</a> und <a href="http://www.miui.com/res/doc/eula.html?region=%3$s&lang=%4$s">Nutzervereinbarung</a> gelesen und akzeptiert haben.</Data>"
In the first case in the address &, in the second &
str = StringUtils.replace(str, "&", "&"); changes in the line in the second case & to &amp;
Here's the line after apktool 2.5.1:
    <string name="privacy_authorize_dialog_message"><Data>Um grundlegende Funktionen dieses Dienstes nutzen zu können, müssen Sie zustimmen, dass Xiaomi Ihre persönlichen Daten erhebt, verarbeitet und nutzt. In unserer Datenschutzerklärung erfahren Sie, wie wir personenbezogene Daten erheben und verarbeiten. \"Zustimmen\" wählen bedeutet, dass Sie unsere <a href=\"https://privacy.mi.com/all/%1$s_%2$s\">Datenschutzerklärung</a> und <a href=\"http://www.miui.com/res/doc/eula.html?region=%3$s&amp;lang=%4$s\">Nutzervereinbarung</a> gelesen und akzeptiert haben.</Data></string>
str = XmlEscape.unescapeXml(str); will bring lines of this type back to normal (apktool 2.6.1 latest snapshot with addition):
    <string name="privacy_authorize_dialog_message"><Data>Um grundlegende Funktionen dieses Dienstes nutzen zu können, müssen Sie zustimmen, dass Xiaomi Ihre persönlichen Daten erhebt, verarbeitet und nutzt. In unserer Datenschutzerklärung erfahren Sie, wie wir personenbezogene Daten erheben und verarbeiten. \"Zustimmen\" wählen bedeutet, dass Sie unsere <a href=\"https://privacy.mi.com/all/%1$s_%2$s\">Datenschutzerklärung</a> und <a href=\"http://www.miui.com/res/doc/eula.html?region=%3$s&lang=%4$s\">Nutzervereinbarung</a> gelesen und akzeptiert haben.</Data></string>
str = HtmlEscape.unescapeHtml(str) will make the lines readable:


:
After this change, apktool 2.6.1 latest snapshot began to decompile Settings.apk
If you or anyone likes it, please create Pull Requests.
thank @pashamcr for the detailed breakdown. It looks like the issue is somewhere prior where we are improperly encoding resources (or just picking a few) while we could probably just use a proper XML encoding process.
Going to close this one for https://github.com/iBotPeaches/Apktool/issues/2890
I believe the path on this is wrong as the root issue is the new attribute splitter we introduced and not related to escaping/unescaping.