Loading tools/aapt2/integration-tests/AutoVersionTest/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -18,4 +18,7 @@ package="com.android.aapt.autoversiontest"> <uses-sdk android:minSdkVersion="7" /> <application> <uses-library android:name="clockwork-system" /> </application> </manifest> tools/aapt2/link/ManifestFixer.cpp +38 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,22 @@ using android::StringPiece; namespace aapt { static bool RequiredNameIsNotEmpty(xml::Element* el, SourcePathDiagnostics* diag) { xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } if (attr->value.empty()) { diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name << "> tag must not be empty"); return false; } return true; } // This is how PackageManager builds class names from AndroidManifest.xml entries. static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr, SourcePathDiagnostics* diag) { Loading Loading @@ -59,23 +75,31 @@ static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* } static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { return NameIsJavaClassName(el, attr, diag); } xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } return NameIsJavaClassName(el, attr, diag); } static bool RequiredNameIsJavaPackage(xml::Element* el, SourcePathDiagnostics* diag) { if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { return util::IsJavaPackageName(attr->value); } xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } if (!util::IsJavaPackageName(attr->value)) { diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name << "> tag must be a valid Java package name"); return false; } return true; } static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) { return [=](xml::Element* el, SourcePathDiagnostics* diag) -> bool { if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) { Loading Loading @@ -213,8 +237,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, // Common <intent-filter> actions. xml::XmlNodeAction intent_filter_action; intent_filter_action["action"]; intent_filter_action["category"]; intent_filter_action["action"].Action(RequiredNameIsNotEmpty); intent_filter_action["category"].Action(RequiredNameIsNotEmpty); intent_filter_action["data"]; // Common <meta-data> actions. Loading Loading @@ -317,8 +341,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, xml::XmlNodeAction& application_action = manifest_action["application"]; application_action.Action(OptionalNameIsJavaClassName); application_action["uses-library"].Action(RequiredNameIsJavaPackage); application_action["library"].Action(RequiredNameIsJavaPackage); application_action["uses-library"].Action(RequiredNameIsNotEmpty); application_action["library"].Action(RequiredNameIsNotEmpty); xml::XmlNodeAction& static_library_action = application_action["static-library"]; static_library_action.Action(RequiredNameIsJavaPackage); Loading tools/aapt2/link/ManifestFixer_test.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -494,4 +494,34 @@ TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) { ASSERT_THAT(manifest, IsNull()); } TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) { std::string input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library android:name="" /> </application> </manifest>)"; EXPECT_THAT(Verify(input), IsNull()); input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library /> </application> </manifest>)"; EXPECT_THAT(Verify(input), IsNull()); input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library android:name="blahhh" /> </application> </manifest>)"; EXPECT_THAT(Verify(input), NotNull()); } } // namespace aapt Loading
tools/aapt2/integration-tests/AutoVersionTest/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -18,4 +18,7 @@ package="com.android.aapt.autoversiontest"> <uses-sdk android:minSdkVersion="7" /> <application> <uses-library android:name="clockwork-system" /> </application> </manifest>
tools/aapt2/link/ManifestFixer.cpp +38 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,22 @@ using android::StringPiece; namespace aapt { static bool RequiredNameIsNotEmpty(xml::Element* el, SourcePathDiagnostics* diag) { xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } if (attr->value.empty()) { diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name << "> tag must not be empty"); return false; } return true; } // This is how PackageManager builds class names from AndroidManifest.xml entries. static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr, SourcePathDiagnostics* diag) { Loading Loading @@ -59,23 +75,31 @@ static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* } static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { return NameIsJavaClassName(el, attr, diag); } xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } return NameIsJavaClassName(el, attr, diag); } static bool RequiredNameIsJavaPackage(xml::Element* el, SourcePathDiagnostics* diag) { if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { return util::IsJavaPackageName(attr->value); } xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); if (attr == nullptr) { diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } if (!util::IsJavaPackageName(attr->value)) { diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name << "> tag must be a valid Java package name"); return false; } return true; } static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) { return [=](xml::Element* el, SourcePathDiagnostics* diag) -> bool { if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) { Loading Loading @@ -213,8 +237,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, // Common <intent-filter> actions. xml::XmlNodeAction intent_filter_action; intent_filter_action["action"]; intent_filter_action["category"]; intent_filter_action["action"].Action(RequiredNameIsNotEmpty); intent_filter_action["category"].Action(RequiredNameIsNotEmpty); intent_filter_action["data"]; // Common <meta-data> actions. Loading Loading @@ -317,8 +341,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, xml::XmlNodeAction& application_action = manifest_action["application"]; application_action.Action(OptionalNameIsJavaClassName); application_action["uses-library"].Action(RequiredNameIsJavaPackage); application_action["library"].Action(RequiredNameIsJavaPackage); application_action["uses-library"].Action(RequiredNameIsNotEmpty); application_action["library"].Action(RequiredNameIsNotEmpty); xml::XmlNodeAction& static_library_action = application_action["static-library"]; static_library_action.Action(RequiredNameIsJavaPackage); Loading
tools/aapt2/link/ManifestFixer_test.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -494,4 +494,34 @@ TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) { ASSERT_THAT(manifest, IsNull()); } TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) { std::string input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library android:name="" /> </application> </manifest>)"; EXPECT_THAT(Verify(input), IsNull()); input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library /> </application> </manifest>)"; EXPECT_THAT(Verify(input), IsNull()); input = R"( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application> <uses-library android:name="blahhh" /> </application> </manifest>)"; EXPECT_THAT(Verify(input), NotNull()); } } // namespace aapt