diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp index 708bed80555b1..90fc10add7e6d 100644 --- a/tools/aapt2/cmd/Util.cpp +++ b/tools/aapt2/cmd/Util.cpp @@ -140,12 +140,27 @@ static xml::NamespaceDecl CreateAndroidNamespaceDecl() { return decl; } +// Returns a copy of 'name' which conforms to the regex '[a-zA-Z]+[a-zA-Z0-9_]*' by +// replacing nonconforming characters with underscores. +// +// See frameworks/base/core/java/android/content/pm/PackageParser.java which +// checks this at runtime. static std::string MakePackageSafeName(const std::string &name) { std::string result(name); + bool first = true; for (char &c : result) { - if (c == '-') { - c = '_'; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + first = false; + continue; } + if (!first) { + if (c >= '0' && c <= '9') { + continue; + } + } + + c = '_'; + first = false; } return result; } diff --git a/tools/aapt2/cmd/Util_test.cpp b/tools/aapt2/cmd/Util_test.cpp index 9c33135f228d9..0c527f6a90dc3 100644 --- a/tools/aapt2/cmd/Util_test.cpp +++ b/tools/aapt2/cmd/Util_test.cpp @@ -24,15 +24,16 @@ namespace aapt { TEST(UtilTest, SplitNamesAreSanitized) { AppInfo app_info{"com.pkg"}; - SplitConstraints split_constraints{{test::ParseConfigOrDie("en-rUS-land")}}; + SplitConstraints split_constraints{ + {test::ParseConfigOrDie("en-rUS-land"), test::ParseConfigOrDie("b+sr+Latn")}}; const auto doc = GenerateSplitManifest(app_info, split_constraints); const auto &root = doc->root; EXPECT_EQ(root->name, "manifest"); - // split names cannot contain hyphens - EXPECT_EQ(root->FindAttribute("", "split")->value, "config.en_rUS_land"); + // split names cannot contain hyphens or plus signs. + EXPECT_EQ(root->FindAttribute("", "split")->value, "config.b_sr_Latn_en_rUS_land"); // but we should use resource qualifiers verbatim in 'targetConfig'. - EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "en-rUS-land"); + EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land"); } } // namespace aapt