From ce15b50c1c1d8280e0ceb94e3f678dc6f499f527 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Mon, 22 Sep 2014 18:27:25 -0500 Subject: [PATCH] handles / that require formatted="false" attributes --- CHANGES | 1 + .../brut/androlib/res/data/value/ResArrayValue.java | 10 ++++++++++ .../brut/androlib/res/data/value/ResScalarValue.java | 4 ++++ .../java/brut/androlib/res/xml/ResXmlEncoders.java | 8 +++++++- .../brut/apktool/testapp/res/values-mcc001/arrays.xml | 3 +++ .../brut/apktool/testapp/res/values-mcc001/strings.xml | 1 + 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b9e72f2c..c0510e66 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ v2.0.0 (TBA) -Fixed (issue #630) - Fixed handling renamed manifests with ("com.lge") -Fixed (issue #409) - Fixed array items incorrectly typed. -Fixed (issue #512) - Fixed AndroidManifest missing attributes. +-Fixed (issue #677) - Fixed ignoring formatted attribute in . -Fixed issue with APKs with multiple dex files. -Fixed issue with using Apktool without smali/baksmali for ApktoolProperties (Thanks teprrr) -Fixed issue with non-URI standard characters in apk name (Thanks rover12421) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java index e5033be1..525a88c7 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java @@ -53,6 +53,16 @@ public class ResArrayValue extends ResBagValue implements type = (type == null ? "" : type + "-") + "array"; serializer.startTag(null, type); serializer.attribute(null, "name", res.getResSpec().getName()); + + // lets check if we need to add formatted="false" to this array + for (int i = 0; i < mItems.length; i++) { + if (mItems[i].hasMultipleNonPositionalSubstitutions()) { + serializer.attribute(null, "formatted", "false"); + break; + } + } + + // add 's for (int i = 0; i < mItems.length; i++) { serializer.startTag(null, "item"); serializer.text(mItems[i].encodeAsResXmlNonEscapedItemValue()); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java index ff8c3f18..25970ecf 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java @@ -61,6 +61,10 @@ public abstract class ResScalarValue extends ResValue implements return encodeAsResXmlValue().replace("&", "&").replace("<","<"); } + public boolean hasMultipleNonPositionalSubstitutions() throws AndrolibException { + return ResXmlEncoders.hasMultipleNonPositionalSubstitutions(mRawValue); + } + @Override public void serializeToResValuesXml(XmlSerializer serializer, ResResource res) throws IOException, AndrolibException { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java index 4eae8e1f..02f7926d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java @@ -175,9 +175,15 @@ public final class ResXmlEncoders { } int pos; int pos2 = 0; - int length = str.length(); List nonPositional = new ArrayList<>(); List positional = new ArrayList<>(); + + if (str == null) { + return new Duo<>(nonPositional, positional); + } + + int length = str.length(); + while ((pos = str.indexOf('%', pos2)) != -1) { pos2 = pos + 1; if (pos2 == length) { diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/arrays.xml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/arrays.xml index da3f4009..95375d77 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/arrays.xml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/arrays.xml @@ -28,4 +28,7 @@ foo foo2 + + category=temp%temp%foo + diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/strings.xml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/strings.xml index e9cd78fb..edc57120 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/strings.xml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-mcc001/strings.xml @@ -28,4 +28,5 @@ bar" 賞金鬥士14 {id:65538,v:2,tid:20003,mst:1,x:-1,y:-1,a:6000,b:3000,lm:{chp:1000,rep:0,bt:0,mp:[[101,0,1,0],[101,0,1,1],[101,0,1,2],[101,0,1,3],[101,0,1,4],[101,0,1,5],[100,0,0,0],[100,0,0,1],[100,0,0,2],[100,0,0,3],[100,0,0,4],[100,0,0,5]]},rm:{chp:1000,rep:0,bt:0,mp:[[100,0,1,0],[100,0,1,1],[100,0,1,2],[100,0,1,3],[100,0,1,4],[100,0,1,5],[101,0,0,0],[101,0,0,1],[101,0,0,2],[101,0,0,3],[101,0,0,4],[101,0,0,5]]}} {al:[[180,0,7,0,0,1000],[109,0,5,0,0],[109,0,5,2,0],[109,0,5,4,0],[100,0,3,0,0],[100,0,3,1,0],[100,0,3,2,0],[100,0,3,3,0],[100,0,3,4,0],[100,0,3,5,0],[103,0,1,0,0],[103,0,1,1,0],[103,0,1,2,0],[103,0,1,3,0],[103,0,1,4,0],[103,0,1,5,0],[106,0,2,0,0],[106,0,2,1,0],[106,0,2,2,0],[106,0,2,3,0],[106,0,2,4,0],[106,0,2,5,0],[800,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[850],[950],[900,0],[1000,0,0]],v:4,s:-1575044211,rl:[[180,0,7,0,0,1000],[103,0,0,0,0],[103,0,0,1,0],[103,0,0,2,0],[103,0,0,3,0],[103,0,0,4,0],[103,0,0,5,0],[111,0,3,0,0],[111,0,3,1,0],[111,0,3,2,0],[111,0,3,3,0],[111,0,3,4,0],[111,0,3,5,0],[102,0,4,0,0],[102,0,4,1,0],[102,0,4,2,0],[102,0,4,3,0],[102,0,4,4,0],[102,0,4,5,0],[107,0,5,0,0],[107,0,5,1,0],[107,0,5,2,0],[107,0,5,3,0],[107,0,5,4,0],[107,0,5,5,0],[106,0,2,0,0],[106,0,2,1,0],[106,0,2,2,0],[106,0,2,3,0],[106,0,2,4,0],[106,0,2,5,0],[900],[1000,0,0]],m:[]} + category=temp%temp%foo