From 247735c434fdd53cdd3da68876e0b2627b8190a8 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Mon, 16 Oct 2023 07:15:34 -0400 Subject: [PATCH] feat: de-dupe attribute names during styles writing (#3404) --- .../brut/androlib/res/data/value/ResStyleValue.java | 12 ++++++++++++ .../java/brut/androlib/res/data/value/ResValue.java | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java index 397431bf..9cf6d74d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java @@ -24,6 +24,8 @@ import brut.util.Duo; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Logger; public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializable { @@ -47,6 +49,8 @@ public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializab } else if (res.getResSpec().getName().indexOf('.') != -1) { serializer.attribute(null, "parent", ""); } + + Set processedNames = new HashSet<>(); for (Duo mItem : mItems) { ResResSpec spec = mItem.m1.getReferent(); @@ -70,6 +74,11 @@ public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializab name = "@" + spec.getFullName(res.getResSpec().getPackage(), false); } + // #3400 - Skip duplicate values, commonly seen are duplicate key-pairs on styles. + if (!isAnalysisMode() && processedNames.contains(name)) { + continue; + } + if (value == null) { value = mItem.m2.encodeAsResXmlValue(); } @@ -82,8 +91,11 @@ public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializab serializer.attribute(null, "name", name); serializer.text(value); serializer.endTag(null, "item"); + + processedNames.add(name); } serializer.endTag(null, "style"); + processedNames.clear(); } private final Duo[] mItems; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java index dec2394e..1b535e6c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java @@ -22,4 +22,8 @@ public class ResValue { public boolean shouldRemoveUnknownRes() { return Config.getInstance().isDecodeResolveModeRemoving(); } + + public boolean isAnalysisMode() { + return Config.getInstance().analysisMode; + } }