diff options
author | 2019-03-19 13:38:34 +0000 | |
---|---|---|
committer | 2019-03-19 16:45:31 +0000 | |
commit | f1d973dd98e1f95a28718ab25c8452be3639708a (patch) | |
tree | 1d936d4d69790a76822906c7df6ee07630a68ce4 | |
parent | 6c5ed85653345b78c17faacf5e26a8e872b510f0 (diff) |
Fix PrintableString() for 4-byte UTF-8 sequences.
Test: Additional test in utf_test.
Bug: 128865240
Change-Id: I535e028319393abb17ee258086e47593f80f4ed3
-rw-r--r-- | libdexfile/dex/utf.cc | 7 | ||||
-rw-r--r-- | libdexfile/dex/utf_test.cc | 20 |
2 files changed, 25 insertions, 2 deletions
diff --git a/libdexfile/dex/utf.cc b/libdexfile/dex/utf.cc index ed07568fbc..3eb80b118e 100644 --- a/libdexfile/dex/utf.cc +++ b/libdexfile/dex/utf.cc @@ -283,10 +283,10 @@ std::string PrintableChar(uint16_t ch) { return result; } -std::string PrintableString(const char* utf) { +std::string PrintableString(const char* utf8) { std::string result; result += '"'; - const char* p = utf; + const char* p = utf8; size_t char_count = CountModifiedUtf8Chars(p); for (size_t i = 0; i < char_count; ++i) { uint32_t ch = GetUtf16FromUtf8(&p); @@ -311,6 +311,9 @@ std::string PrintableString(const char* utf) { if (trailing != 0) { // All high surrogates will need escaping. StringAppendF(&result, "\\u%04x", trailing); + // Account for the surrogate pair. + ++i; + DCHECK_LT(i, char_count); } } } diff --git a/libdexfile/dex/utf_test.cc b/libdexfile/dex/utf_test.cc index c7a6a342ff..919259e4d3 100644 --- a/libdexfile/dex/utf_test.cc +++ b/libdexfile/dex/utf_test.cc @@ -19,6 +19,8 @@ #include <map> #include <vector> +#include <android-base/stringprintf.h> + #include "gtest/gtest.h" #include "utf-inl.h" @@ -385,4 +387,22 @@ TEST_F(UtfTest, NonAscii) { EXPECT_EQ(static_cast<uint8_t>(kNonAsciiCharacter), hash); } +TEST_F(UtfTest, PrintableStringUtf8) { + // Note: This is UTF-8, not Modified-UTF-8. + const uint8_t kTestSequence[] = { 0xf0, 0x90, 0x80, 0x80, 0 }; + const char* start = reinterpret_cast<const char*>(kTestSequence); + const char* ptr = start; + uint32_t pair = GetUtf16FromUtf8(&ptr); + ASSERT_EQ(*ptr, '\0'); + uint16_t leading = GetLeadingUtf16Char(pair); + uint16_t trailing = GetTrailingUtf16Char(pair); + ASSERT_NE(0u, trailing); + + std::string expected = android::base::StringPrintf("\"\\u%04x\\u%04x\"", + static_cast<unsigned>(leading), + static_cast<unsigned>(trailing)); + std::string printable = PrintableString(start); + EXPECT_EQ(expected, printable); +} + } // namespace art |