Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,11 @@ public ResourceEntry encodeAttributeName(String uri, String prefix, String name)
setName(name, 0);
return null;
}
ResourceEntry resourceEntry = super.encodeAttrName(prefix, name);
String lookupPrefix = prefix;
if (Namespace.URI_ANDROID.equals(uri)) {
lookupPrefix = Namespace.PREFIX_ANDROID;
}
ResourceEntry resourceEntry = super.encodeAttrName(lookupPrefix, name);
if (resourceEntry != null) {
return resourceEntry;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.reandroid.arsc.chunk.xml;

import com.reandroid.apk.AndroidFrameworks;
import com.reandroid.apk.ApkModule;
import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.xml.XMLFactory;
import org.junit.Assert;
import org.junit.Test;

public class Pr111NamespaceRegressionTest {

private ResXmlDocument parse(String xml) throws Exception {
TableBlock table = new TableBlock();
table.addFramework(
AndroidFrameworks.getLatest().getTableBlock());
table.refresh();

ApkModule apk = new ApkModule();
apk.setTableBlock(table);

ResXmlDocument doc = new ResXmlDocument();
doc.setApkFile(apk);
doc.parse(XMLFactory.newPullParser(xml));
return doc;
}

@Test
public void standardAndroidPrefix() throws Exception {
ResXmlDocument doc = parse(
"<manifest xmlns:android=\"" +
"http://schemas.android.com/apk/res/android\" " +
"android:versionCode=\"123\"/>");

ResXmlAttribute attr = doc.getDocumentElement()
.searchAttributeByName("versionCode");

Assert.assertNotNull(attr);
Assert.assertEquals("android", attr.getPrefix());
Assert.assertTrue(attr.getNameId() != 0);
Assert.assertEquals(123, attr.getData());
}

@Test
public void alternateAndroidPrefix() throws Exception {
ResXmlDocument doc = parse(
"<manifest xmlns:n0=\"" +
"http://schemas.android.com/apk/res/android\" " +
"n0:versionCode=\"456\"/>");

ResXmlAttribute attr = doc.getDocumentElement()
.searchAttributeByName("versionCode");

Assert.assertNotNull(attr);
Assert.assertEquals(
"http://schemas.android.com/apk/res/android",
attr.getUri());
// Prefix may be normalized internally.
// Verify namespace URI, resource ID and value instead.
Assert.assertTrue(attr.getNameId() != 0);
Assert.assertEquals(456, attr.getData());
}

@Test
public void externalNamespaceMustNotBecomeAndroid()
throws Exception {
ResXmlDocument doc = parse(
"<manifest xmlns:n0=\"https://example.com/custom\" " +
"n0:versionCode=\"789\"/>");

ResXmlAttribute attr = doc.getDocumentElement()
.searchAttributeByName("versionCode");

Assert.assertNotNull(attr);
Assert.assertEquals(
"https://example.com/custom",
attr.getUri());
Assert.assertEquals(0, attr.getNameId());
}
}
77 changes: 77 additions & 0 deletions src/test/java/com/reandroid/arsc/chunk/xml/ResXmlDocumentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,83 @@ public void testEncodeDecodeXml() throws XmlPullParserException, IOException {
decoded = decoded.replaceAll("\\s+", "");
Assert.assertEquals(org, decoded);
}

@Test
public void testIssue202AlternateAndroidNamespace()
throws Exception {

String xml =
"<manifest " +
"xmlns:n0=\"http://schemas.android.com/apk/res/android\" " +
"n0:versionCode=\"733700004\" " +
"n0:versionName=\"137.0.7337.0\" " +
"package=\"com.kiwibrowser.browser\">" +
"<uses-sdk n0:minSdkVersion=\"24\" " +
"n0:targetSdkVersion=\"34\"/>" +
"</manifest>";

ResXmlDocument document = new ResXmlDocument();
document.setApkFile(createEmptyApkModule());
document.parse(XMLFactory.newPullParser(xml));

ResXmlElement root = document.getDocumentElement();
Assert.assertNotNull(root);

ResXmlAttribute version =
root.searchAttributeByName("versionCode");
Assert.assertNotNull(version);
Assert.assertEquals("http://schemas.android.com/apk/res/android", version.getUri());

ResXmlElement sdk = root.getElement("uses-sdk");
Assert.assertNotNull(sdk);
Assert.assertNotNull(
sdk.searchAttributeByName("targetSdkVersion"));

document.refreshFull();

StringWriter writer = new StringWriter();
XmlSerializer serializer = XMLFactory.newSerializer(writer);
document.serialize(serializer);

String output = writer.toString();
Assert.assertTrue(output.contains("733700004"));
Assert.assertTrue(output.contains("137.0.7337.0"));
}


@Test
public void testIssue202JsonNamespaceRoundTrip()
throws Exception {

String xml =
"<manifest " +
"xmlns:n0=\"http://schemas.android.com/apk/res/android\" " +
"n0:versionCode=\"733700004\" " +
"package=\"com.kiwibrowser.browser\"/>";

ResXmlDocument original = new ResXmlDocument();
original.setApkFile(createEmptyApkModule());
original.parse(XMLFactory.newPullParser(xml));

com.reandroid.json.JSONObject json = original.toJson();

ResXmlDocument restored = new ResXmlDocument();
restored.setApkFile(createEmptyApkModule());
restored.fromJson(json);

ResXmlElement root = restored.getDocumentElement();
Assert.assertNotNull(root);

ResXmlAttribute version =
root.searchAttributeByName("versionCode");

Assert.assertNotNull(version);
Assert.assertEquals(
"http://schemas.android.com/apk/res/android",
version.getUri());
Assert.assertEquals(733700004, version.getData());
}

private static ApkModule createEmptyApkModule() throws IOException {
ApkModule apkModule = new ApkModule();
apkModule.setTableBlock(createEmptyTable());
Expand Down