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