From 71965e898ecb2d53972a98e63b3e3fdbe96542dc Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Thu, 7 Jul 2016 17:12:12 -0700 Subject: [PATCH] AAPT2: Fix fully qualified java class verification Proguard rules would be ignored for components defined in AndroidManifest.xml for android:name attributes if they didn't start with '.'. Change-Id: I029b5a2f224f4daf155b73a2a4dcd940dd43372e --- tools/aapt2/link/ManifestFixer.cpp | 23 +++++++++++------------ tools/aapt2/util/Util.cpp | 4 ++-- tools/aapt2/util/Util_test.cpp | 9 +++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 45e07a7a337f..db6e06dfa6c3 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -20,6 +20,8 @@ #include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" +#include + namespace aapt { /** @@ -27,21 +29,14 @@ namespace aapt { */ static bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr, SourcePathDiagnostics* diag) { - std::u16string className = attr->value; - if (className.find(u'.') == std::u16string::npos) { - // There is no '.', so add one to the beginning. - className = u"."; - className += attr->value; - } - // We allow unqualified class names (ie: .HelloActivity) // Since we don't know the package name, we can just make a fake one here and // the test will be identical as long as the real package name is valid too. Maybe fullyQualifiedClassName = - util::getFullyQualifiedClassName(u"a", className); + util::getFullyQualifiedClassName(u"a", attr->value); StringPiece16 qualifiedClassName = fullyQualifiedClassName - ? fullyQualifiedClassName.value() : className; + ? fullyQualifiedClassName.value() : attr->value; if (!util::isJavaClassName(qualifiedClassName)) { diag->error(DiagMessage(el->lineNumber) << "attribute 'android:name' in <" @@ -230,9 +225,12 @@ public: void visit(xml::Element* el) override { for (xml::Attribute& attr : el->attributes) { - if (Maybe newValue = - util::getFullyQualifiedClassName(mPackage, attr.value)) { - attr.value = std::move(newValue.value()); + if (attr.namespaceUri == xml::kSchemaAndroid + && mClassAttributes.find(attr.name) != mClassAttributes.end()) { + if (Maybe newValue = + util::getFullyQualifiedClassName(mPackage, attr.value)) { + attr.value = std::move(newValue.value()); + } } } @@ -242,6 +240,7 @@ public: private: StringPiece16 mPackage; + std::unordered_set mClassAttributes = { u"name" }; }; static bool renameManifestPackage(const StringPiece16& packageOverride, xml::Element* manifestEl) { diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp index 7b0c71d93bb5..5748a1269072 100644 --- a/tools/aapt2/util/Util.cpp +++ b/tools/aapt2/util/Util.cpp @@ -175,11 +175,11 @@ Maybe getFullyQualifiedClassName(const StringPiece16& package, return {}; } + std::u16string result(package.data(), package.size()); if (className.data()[0] != u'.') { - return {}; + result += u'.'; } - std::u16string result(package.data(), package.size()); result.append(className.data(), className.size()); if (!isJavaClassName(result)) { return {}; diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp index 1e0c7fa9152d..fad1afb847ff 100644 --- a/tools/aapt2/util/Util_test.cpp +++ b/tools/aapt2/util/Util_test.cpp @@ -143,10 +143,7 @@ TEST(UtilTest, IsJavaPackageName) { } TEST(UtilTest, FullyQualifiedClassName) { - Maybe res = util::getFullyQualifiedClassName(u"android", u"asdf"); - AAPT_ASSERT_FALSE(res); - - res = util::getFullyQualifiedClassName(u"android", u".asdf"); + Maybe res = util::getFullyQualifiedClassName(u"android", u".asdf"); AAPT_ASSERT_TRUE(res); EXPECT_EQ(res.value(), u"android.asdf"); @@ -162,6 +159,10 @@ TEST(UtilTest, FullyQualifiedClassName) { AAPT_ASSERT_TRUE(res); EXPECT_EQ(res.value(), u"a.b"); + res = util::getFullyQualifiedClassName(u"android", u"Class"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), u"android.Class"); + res = util::getFullyQualifiedClassName(u"", u""); AAPT_ASSERT_FALSE(res); -- 2.11.0