Loading tools/aapt2/java/ManifestClassGenerator.cpp +10 −22 Original line number Original line Diff line number Diff line Loading @@ -21,24 +21,21 @@ #include "Source.h" #include "Source.h" #include "java/AnnotationProcessor.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" #include "java/ClassDefinition.h" #include "text/Unicode.h" #include "util/Maybe.h" #include "util/Maybe.h" #include "xml/XmlDom.h" #include "xml/XmlDom.h" using android::StringPiece; using android::StringPiece; using ::aapt::text::IsJavaIdentifier; namespace aapt { namespace aapt { static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source, const Source& source, const std::string& value) { const StringPiece& value) { StringPiece result = value; const StringPiece sep = "."; size_t pos = value.rfind('.'); auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end()); if (pos != std::string::npos) { result = result.substr(pos + 1); StringPiece result; if (iter != value.end()) { result.assign(iter + sep.size(), value.end() - (iter + sep.size())); } else { result = value; } } if (result.empty()) { if (result.empty()) { Loading @@ -46,19 +43,10 @@ static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, return {}; return {}; } } iter = util::FindNonAlphaNumericAndNotInSet(result, "_"); if (!IsJavaIdentifier(result)) { if (iter != result.end()) { diag->Error(DiagMessage(source) << "invalid Java identifier '" << result << "'"); diag->Error(DiagMessage(source) << "invalid character '" << StringPiece(iter, 1) << "' in '" << result << "'"); return {}; return {}; } } if (*result.begin() >= '0' && *result.begin() <= '9') { diag->Error(DiagMessage(source) << "symbol can not start with a digit"); return {}; } return result; return result; } } Loading tools/aapt2/link/ManifestFixer.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -127,9 +127,9 @@ static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { diag->Error(DiagMessage(el->line_number) diag->Error(DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag must not be a reference"); << "attribute 'package' in <manifest> tag must not be a reference"); return false; return false; } else if (!util::IsJavaPackageName(attr->value)) { } else if (!util::IsAndroidPackageName(attr->value)) { diag->Error(DiagMessage(el->line_number) diag->Error(DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag is not a valid Java package name: '" << "attribute 'package' in <manifest> tag is not a valid Android package name: '" << attr->value << "'"); << attr->value << "'"); return false; return false; } } Loading tools/aapt2/text/Unicode.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -85,7 +85,8 @@ bool IsJavaIdentifier(const StringPiece& str) { return false; return false; } } if (!IsXidStart(iter.Next())) { const char32_t first_codepoint = iter.Next(); if (!IsXidStart(first_codepoint) && first_codepoint != U'_' && first_codepoint != U'$') { return false; return false; } } Loading tools/aapt2/text/Unicode_test.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -44,10 +44,11 @@ TEST(UnicodeTest, IsXidContinue) { TEST(UnicodeTest, IsJavaIdentifier) { TEST(UnicodeTest, IsJavaIdentifier) { EXPECT_TRUE(IsJavaIdentifier("FøøBar_12")); EXPECT_TRUE(IsJavaIdentifier("FøøBar_12")); EXPECT_TRUE(IsJavaIdentifier("Føø$Bar")); EXPECT_TRUE(IsJavaIdentifier("Føø$Bar")); EXPECT_TRUE(IsJavaIdentifier("_FøøBar")); EXPECT_TRUE(IsJavaIdentifier("$Føø$Bar")); EXPECT_FALSE(IsJavaIdentifier("12FøøBar")); EXPECT_FALSE(IsJavaIdentifier("12FøøBar")); EXPECT_FALSE(IsJavaIdentifier("_FøøBar")); EXPECT_FALSE(IsJavaIdentifier(".Hello")); EXPECT_FALSE(IsJavaIdentifier("$Føø$Bar")); } } TEST(UnicodeTest, IsValidResourceEntryName) { TEST(UnicodeTest, IsValidResourceEntryName) { Loading tools/aapt2/util/Util.cpp +34 −50 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "androidfw/StringPiece.h" #include "androidfw/StringPiece.h" #include "utils/Unicode.h" #include "utils/Unicode.h" #include "text/Unicode.h" #include "text/Utf8Iterator.h" #include "text/Utf8Iterator.h" #include "util/BigBuffer.h" #include "util/BigBuffer.h" #include "util/Maybe.h" #include "util/Maybe.h" Loading Loading @@ -94,72 +95,55 @@ StringPiece TrimWhitespace(const StringPiece& str) { return StringPiece(start, end - start); return StringPiece(start, end - start); } } StringPiece::const_iterator FindNonAlphaNumericAndNotInSet( static int IsJavaNameImpl(const StringPiece& str) { const StringPiece& str, const StringPiece& allowed_chars) { int pieces = 0; const auto end_iter = str.end(); for (const StringPiece& piece : Tokenize(str, '.')) { for (auto iter = str.begin(); iter != end_iter; ++iter) { pieces++; char c = *iter; if (!text::IsJavaIdentifier(piece)) { if ((c >= u'a' && c <= u'z') || (c >= u'A' && c <= u'Z') || return -1; (c >= u'0' && c <= u'9')) { continue; } } bool match = false; for (char i : allowed_chars) { if (c == i) { match = true; break; } } return pieces; } } if (!match) { bool IsJavaClassName(const StringPiece& str) { return iter; return IsJavaNameImpl(str) >= 2; } } } return end_iter; bool IsJavaPackageName(const StringPiece& str) { return IsJavaNameImpl(str) >= 1; } } bool IsJavaClassName(const StringPiece& str) { static int IsAndroidNameImpl(const StringPiece& str) { size_t pieces = 0; int pieces = 0; for (const StringPiece& piece : Tokenize(str, '.')) { for (const StringPiece& piece : Tokenize(str, '.')) { pieces++; if (piece.empty()) { if (piece.empty()) { return false; return -1; } } // Can't have starting or trailing $ character. const char first_character = piece.data()[0]; if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') { if (!::isalpha(first_character)) { return false; return -1; } } if (FindNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) { bool valid = std::all_of(piece.begin() + 1, piece.end(), [](const char c) -> bool { return false; return ::isalnum(c) || c == '_'; } }); } return pieces >= 2; } bool IsJavaPackageName(const StringPiece& str) { if (!valid) { if (str.empty()) { return -1; return false; } } size_t pieces = 0; for (const StringPiece& piece : Tokenize(str, '.')) { pieces++; pieces++; if (piece.empty()) { return false; } } return pieces; if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') { return false; } } if (FindNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) { bool IsAndroidPackageName(const StringPiece& str) { return false; return IsAndroidNameImpl(str) > 1 || str == "android"; } } } return pieces >= 1; bool IsAndroidSplitName(const StringPiece& str) { return IsAndroidNameImpl(str) > 0; } } Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, Loading @@ -176,7 +160,7 @@ Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, return {}; return {}; } } std::string result(package.data(), package.size()); std::string result = package.to_string(); if (classname.data()[0] != '.') { if (classname.data()[0] != '.') { result += '.'; result += '.'; } } Loading Loading
tools/aapt2/java/ManifestClassGenerator.cpp +10 −22 Original line number Original line Diff line number Diff line Loading @@ -21,24 +21,21 @@ #include "Source.h" #include "Source.h" #include "java/AnnotationProcessor.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" #include "java/ClassDefinition.h" #include "text/Unicode.h" #include "util/Maybe.h" #include "util/Maybe.h" #include "xml/XmlDom.h" #include "xml/XmlDom.h" using android::StringPiece; using android::StringPiece; using ::aapt::text::IsJavaIdentifier; namespace aapt { namespace aapt { static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source, const Source& source, const std::string& value) { const StringPiece& value) { StringPiece result = value; const StringPiece sep = "."; size_t pos = value.rfind('.'); auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end()); if (pos != std::string::npos) { result = result.substr(pos + 1); StringPiece result; if (iter != value.end()) { result.assign(iter + sep.size(), value.end() - (iter + sep.size())); } else { result = value; } } if (result.empty()) { if (result.empty()) { Loading @@ -46,19 +43,10 @@ static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, return {}; return {}; } } iter = util::FindNonAlphaNumericAndNotInSet(result, "_"); if (!IsJavaIdentifier(result)) { if (iter != result.end()) { diag->Error(DiagMessage(source) << "invalid Java identifier '" << result << "'"); diag->Error(DiagMessage(source) << "invalid character '" << StringPiece(iter, 1) << "' in '" << result << "'"); return {}; return {}; } } if (*result.begin() >= '0' && *result.begin() <= '9') { diag->Error(DiagMessage(source) << "symbol can not start with a digit"); return {}; } return result; return result; } } Loading
tools/aapt2/link/ManifestFixer.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -127,9 +127,9 @@ static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { diag->Error(DiagMessage(el->line_number) diag->Error(DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag must not be a reference"); << "attribute 'package' in <manifest> tag must not be a reference"); return false; return false; } else if (!util::IsJavaPackageName(attr->value)) { } else if (!util::IsAndroidPackageName(attr->value)) { diag->Error(DiagMessage(el->line_number) diag->Error(DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag is not a valid Java package name: '" << "attribute 'package' in <manifest> tag is not a valid Android package name: '" << attr->value << "'"); << attr->value << "'"); return false; return false; } } Loading
tools/aapt2/text/Unicode.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -85,7 +85,8 @@ bool IsJavaIdentifier(const StringPiece& str) { return false; return false; } } if (!IsXidStart(iter.Next())) { const char32_t first_codepoint = iter.Next(); if (!IsXidStart(first_codepoint) && first_codepoint != U'_' && first_codepoint != U'$') { return false; return false; } } Loading
tools/aapt2/text/Unicode_test.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -44,10 +44,11 @@ TEST(UnicodeTest, IsXidContinue) { TEST(UnicodeTest, IsJavaIdentifier) { TEST(UnicodeTest, IsJavaIdentifier) { EXPECT_TRUE(IsJavaIdentifier("FøøBar_12")); EXPECT_TRUE(IsJavaIdentifier("FøøBar_12")); EXPECT_TRUE(IsJavaIdentifier("Føø$Bar")); EXPECT_TRUE(IsJavaIdentifier("Føø$Bar")); EXPECT_TRUE(IsJavaIdentifier("_FøøBar")); EXPECT_TRUE(IsJavaIdentifier("$Føø$Bar")); EXPECT_FALSE(IsJavaIdentifier("12FøøBar")); EXPECT_FALSE(IsJavaIdentifier("12FøøBar")); EXPECT_FALSE(IsJavaIdentifier("_FøøBar")); EXPECT_FALSE(IsJavaIdentifier(".Hello")); EXPECT_FALSE(IsJavaIdentifier("$Føø$Bar")); } } TEST(UnicodeTest, IsValidResourceEntryName) { TEST(UnicodeTest, IsValidResourceEntryName) { Loading
tools/aapt2/util/Util.cpp +34 −50 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "androidfw/StringPiece.h" #include "androidfw/StringPiece.h" #include "utils/Unicode.h" #include "utils/Unicode.h" #include "text/Unicode.h" #include "text/Utf8Iterator.h" #include "text/Utf8Iterator.h" #include "util/BigBuffer.h" #include "util/BigBuffer.h" #include "util/Maybe.h" #include "util/Maybe.h" Loading Loading @@ -94,72 +95,55 @@ StringPiece TrimWhitespace(const StringPiece& str) { return StringPiece(start, end - start); return StringPiece(start, end - start); } } StringPiece::const_iterator FindNonAlphaNumericAndNotInSet( static int IsJavaNameImpl(const StringPiece& str) { const StringPiece& str, const StringPiece& allowed_chars) { int pieces = 0; const auto end_iter = str.end(); for (const StringPiece& piece : Tokenize(str, '.')) { for (auto iter = str.begin(); iter != end_iter; ++iter) { pieces++; char c = *iter; if (!text::IsJavaIdentifier(piece)) { if ((c >= u'a' && c <= u'z') || (c >= u'A' && c <= u'Z') || return -1; (c >= u'0' && c <= u'9')) { continue; } } bool match = false; for (char i : allowed_chars) { if (c == i) { match = true; break; } } return pieces; } } if (!match) { bool IsJavaClassName(const StringPiece& str) { return iter; return IsJavaNameImpl(str) >= 2; } } } return end_iter; bool IsJavaPackageName(const StringPiece& str) { return IsJavaNameImpl(str) >= 1; } } bool IsJavaClassName(const StringPiece& str) { static int IsAndroidNameImpl(const StringPiece& str) { size_t pieces = 0; int pieces = 0; for (const StringPiece& piece : Tokenize(str, '.')) { for (const StringPiece& piece : Tokenize(str, '.')) { pieces++; if (piece.empty()) { if (piece.empty()) { return false; return -1; } } // Can't have starting or trailing $ character. const char first_character = piece.data()[0]; if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') { if (!::isalpha(first_character)) { return false; return -1; } } if (FindNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) { bool valid = std::all_of(piece.begin() + 1, piece.end(), [](const char c) -> bool { return false; return ::isalnum(c) || c == '_'; } }); } return pieces >= 2; } bool IsJavaPackageName(const StringPiece& str) { if (!valid) { if (str.empty()) { return -1; return false; } } size_t pieces = 0; for (const StringPiece& piece : Tokenize(str, '.')) { pieces++; pieces++; if (piece.empty()) { return false; } } return pieces; if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') { return false; } } if (FindNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) { bool IsAndroidPackageName(const StringPiece& str) { return false; return IsAndroidNameImpl(str) > 1 || str == "android"; } } } return pieces >= 1; bool IsAndroidSplitName(const StringPiece& str) { return IsAndroidNameImpl(str) > 0; } } Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, Loading @@ -176,7 +160,7 @@ Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, return {}; return {}; } } std::string result(package.data(), package.size()); std::string result = package.to_string(); if (classname.data()[0] != '.') { if (classname.data()[0] != '.') { result += '.'; result += '.'; } } Loading