AAPT2: Accept aliases defined for external resource types
Resource types that are typically stored outside of the resource table
(like layout, xml, drawable) can only have aliases (reference to another
resource).
Change-Id: Idb768801f02bb142e5be5e438904f221499bd756
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 981ece7..f2a1878 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -346,8 +346,21 @@
} else if (elementName == u"public-group") {
result = parsePublicGroup(parser, &parsedResource);
} else {
- mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber()))
- << "unknown resource type '" << elementName << "'");
+ // Try parsing the elementName (or type) as a resource. These shall only be
+ // resources like 'layout' or 'xml' and they can only be references.
+ if (const ResourceType* type = parseResourceType(elementName)) {
+ parsedResource.name.type = *type;
+ parsedResource.value = parseXml(parser, android::ResTable_map::TYPE_REFERENCE,
+ false);
+ if (!parsedResource.value) {
+ mDiag->error(DiagMessage(parsedResource.source) << "invalid value for type '"
+ << *type << "'. Expected a reference");
+ result = false;
+ }
+ } else {
+ mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber()))
+ << "unknown resource type '" << elementName << "'");
+ }
}
if (result) {
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index b3ad031..b59eb95 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -521,4 +521,12 @@
EXPECT_EQ(ResourceId(0x01010041), actualId);
}
+TEST_F(ResourceParserTest, ExternalTypesShouldOnlyBeReferences) {
+ std::string input = R"EOF(<item type="layout" name="foo">@layout/bar</item>)EOF";
+ ASSERT_TRUE(testParse(input));
+
+ input = R"EOF(<item type="layout" name="bar">"this is a string"</item>)EOF";
+ ASSERT_FALSE(testParse(input));
+}
+
} // namespace aapt