mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-09 18:24:26 +02:00
Fix: numeric string meta-data value corruption (#2612)
* Fix: handle numeric strings in manifest meta-data value * fix regex * scoped solution * improve comment Co-authored-by: Cody Lund <colund@microsoft.com>
This commit is contained in:
parent
1dddc32636
commit
8d59882e5f
@ -138,7 +138,7 @@ final public class AndrolibResources {
|
|||||||
public void decodeManifest(ResTable resTable, ExtFile apkFile, File outDir)
|
public void decodeManifest(ResTable resTable, ExtFile apkFile, File outDir)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
|
|
||||||
Duo<ResFileDecoder, AXmlResourceParser> duo = getManifestFileDecoder();
|
Duo<ResFileDecoder, AXmlResourceParser> duo = getManifestFileDecoder(false);
|
||||||
ResFileDecoder fileDecoder = duo.m1;
|
ResFileDecoder fileDecoder = duo.m1;
|
||||||
|
|
||||||
// Set ResAttrDecoder
|
// Set ResAttrDecoder
|
||||||
@ -185,7 +185,7 @@ final public class AndrolibResources {
|
|||||||
public void decodeManifestWithResources(ResTable resTable, ExtFile apkFile, File outDir)
|
public void decodeManifestWithResources(ResTable resTable, ExtFile apkFile, File outDir)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
|
|
||||||
Duo<ResFileDecoder, AXmlResourceParser> duo = getResFileDecoder();
|
Duo<ResFileDecoder, AXmlResourceParser> duo = getManifestFileDecoder(true);
|
||||||
ResFileDecoder fileDecoder = duo.m1;
|
ResFileDecoder fileDecoder = duo.m1;
|
||||||
ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder();
|
ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder();
|
||||||
|
|
||||||
@ -708,11 +708,13 @@ final public class AndrolibResources {
|
|||||||
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(decoders), axmlParser);
|
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(decoders), axmlParser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Duo<ResFileDecoder, AXmlResourceParser> getManifestFileDecoder() {
|
public Duo<ResFileDecoder, AXmlResourceParser> getManifestFileDecoder(boolean withResources) {
|
||||||
ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
|
ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
|
||||||
|
|
||||||
AXmlResourceParser axmlParser = new AXmlResourceParser();
|
AXmlResourceParser axmlParser = new AndroidManifestResourceParser();
|
||||||
|
if (withResources) {
|
||||||
|
axmlParser.setAttrDecoder(new ResAttrDecoder());
|
||||||
|
}
|
||||||
decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,getResXmlSerializer()));
|
decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,getResXmlSerializer()));
|
||||||
|
|
||||||
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(decoders), axmlParser);
|
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(decoders), axmlParser);
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
|
* Copyright (C) 2010 Connor Tumbleson <connor.tumbleson@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package brut.androlib.res.decoder;
|
||||||
|
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AXmlResourceParser specifically for parsing encoded AndroidManifest.xml.
|
||||||
|
*/
|
||||||
|
public class AndroidManifestResourceParser extends AXmlResourceParser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pattern for matching numeric string meta-data values. aapt automatically infers the
|
||||||
|
* type for a manifest meta-data value based on the string in the unencoded XML. However,
|
||||||
|
* some apps intentionally coerce integers to be strings by prepending an escaped space.
|
||||||
|
* For details/discussion, see https://stackoverflow.com/questions/2154945/how-to-force-a-meta-data-value-to-type-string
|
||||||
|
* With aapt1, the escaped space is dropped when encoded. For aapt2, the escaped space is preserved.
|
||||||
|
*/
|
||||||
|
private static final Pattern PATTERN_NUMERIC_STRING = Pattern.compile("\\s?\\d+");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAttributeValue(int index) {
|
||||||
|
String value = super.getAttributeValue(index);
|
||||||
|
|
||||||
|
if (!isNumericStringMetadataAttributeValue(index, value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch the numeric string value by prefixing it with an escaped space.
|
||||||
|
// Otherwise, when the decoded app is rebuilt, aapt will incorrectly encode
|
||||||
|
// the value as an int or float (depending on aapt version), breaking the original
|
||||||
|
// app functionality.
|
||||||
|
return "\\ " + super.getAttributeValue(index).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNumericStringMetadataAttributeValue(int index, String value) {
|
||||||
|
return "meta-data".equalsIgnoreCase(super.getName())
|
||||||
|
&& "value".equalsIgnoreCase(super.getAttributeName(index))
|
||||||
|
&& super.getAttributeValueType(index) == TypedValue.TYPE_STRING
|
||||||
|
&& PATTERN_NUMERIC_STRING.matcher(value).matches();
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:appCategory="game" android:compileSdkVersion="23" android:compileSdkVersionCodename="6.0-2438415" package="brut.apktool.testapp" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:appCategory="game" android:compileSdkVersion="23" android:compileSdkVersionCodename="6.0-2438415" package="brut.apktool.testapp" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
|
||||||
<uses-feature android:glEsVersion="0x00020000" />
|
<uses-feature android:glEsVersion="0x00020000" />
|
||||||
<uses-feature android:glEsVersion="0x00030002" />
|
<uses-feature android:glEsVersion="0x00030002" />
|
||||||
|
<application>
|
||||||
|
<meta-data name="test_int_as_string" value="\ 12345" />
|
||||||
|
<meta-data name="test_int" value="12345" />
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:appCategory="game" android:compileSdkVersion="23" android:compileSdkVersionCodename="6.0-2438415" package="brut.apktool.aapt1.testapp" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:appCategory="game" android:compileSdkVersion="23" android:compileSdkVersionCodename="6.0-2438415" package="brut.apktool.aapt1.testapp" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
|
||||||
|
<application>
|
||||||
|
<meta-data name="test_int_as_string" value="\ 12345" />
|
||||||
|
<meta-data name="test_int" value="12345" />
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user