Merge "AAPT2: Fix issue with parsing escape sequences when the parser only gives us part at a time"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b16e74693e
@@ -18,11 +18,11 @@
|
||||
#define AAPT_LOGGER_H
|
||||
|
||||
#include "Source.h"
|
||||
#include "StringPiece.h"
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace aapt {
|
||||
|
||||
@@ -71,11 +71,6 @@ private:
|
||||
Source mSource;
|
||||
};
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) {
|
||||
android::String8 utf8(str.data(), str.size());
|
||||
return out.write(utf8.string(), utf8.size());
|
||||
}
|
||||
|
||||
} // namespace aapt
|
||||
|
||||
#endif // AAPT_LOGGER_H
|
||||
|
||||
@@ -229,4 +229,9 @@ inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<ch
|
||||
|
||||
} // namespace aapt
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) {
|
||||
android::String8 utf8(str.data(), str.size());
|
||||
return out.write(utf8.string(), utf8.size());
|
||||
}
|
||||
|
||||
#endif // AAPT_STRING_PIECE_H
|
||||
|
||||
@@ -175,7 +175,51 @@ StringBuilder& StringBuilder::append(const StringPiece16& str) {
|
||||
const char16_t* start = str.begin();
|
||||
const char16_t* current = start;
|
||||
while (current != end) {
|
||||
if (*current == u'"') {
|
||||
if (mLastCharWasEscape) {
|
||||
switch (*current) {
|
||||
case u't':
|
||||
mStr += u'\t';
|
||||
break;
|
||||
case u'n':
|
||||
mStr += u'\n';
|
||||
break;
|
||||
case u'#':
|
||||
mStr += u'#';
|
||||
break;
|
||||
case u'@':
|
||||
mStr += u'@';
|
||||
break;
|
||||
case u'?':
|
||||
mStr += u'?';
|
||||
break;
|
||||
case u'"':
|
||||
mStr += u'"';
|
||||
break;
|
||||
case u'\'':
|
||||
mStr += u'\'';
|
||||
break;
|
||||
case u'\\':
|
||||
mStr += u'\\';
|
||||
break;
|
||||
case u'u': {
|
||||
current++;
|
||||
Maybe<char16_t> c = parseUnicodeCodepoint(¤t, end);
|
||||
if (!c) {
|
||||
mError = "invalid unicode escape sequence";
|
||||
return *this;
|
||||
}
|
||||
mStr += c.value();
|
||||
current -= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Ignore.
|
||||
break;
|
||||
}
|
||||
mLastCharWasEscape = false;
|
||||
start = current + 1;
|
||||
} else if (*current == u'"') {
|
||||
if (!mQuote && mTrailingSpace) {
|
||||
// We found an opening quote, and we have
|
||||
// trailing space, so we should append that
|
||||
@@ -208,52 +252,7 @@ StringBuilder& StringBuilder::append(const StringPiece16& str) {
|
||||
}
|
||||
mStr.append(start, current - start);
|
||||
start = current + 1;
|
||||
|
||||
current++;
|
||||
if (current != end) {
|
||||
switch (*current) {
|
||||
case u't':
|
||||
mStr += u'\t';
|
||||
break;
|
||||
case u'n':
|
||||
mStr += u'\n';
|
||||
break;
|
||||
case u'#':
|
||||
mStr += u'#';
|
||||
break;
|
||||
case u'@':
|
||||
mStr += u'@';
|
||||
break;
|
||||
case u'?':
|
||||
mStr += u'?';
|
||||
break;
|
||||
case u'"':
|
||||
mStr += u'"';
|
||||
break;
|
||||
case u'\'':
|
||||
mStr += u'\'';
|
||||
break;
|
||||
case u'\\':
|
||||
mStr += u'\\';
|
||||
break;
|
||||
case u'u': {
|
||||
current++;
|
||||
Maybe<char16_t> c = parseUnicodeCodepoint(¤t, end);
|
||||
if (!c) {
|
||||
mError = "invalid unicode escape sequence";
|
||||
return *this;
|
||||
}
|
||||
mStr += c.value();
|
||||
current -= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Ignore.
|
||||
break;
|
||||
}
|
||||
start = current + 1;
|
||||
}
|
||||
mLastCharWasEscape = true;
|
||||
} else if (!mQuote) {
|
||||
// This is not quoted text, so look for whitespace.
|
||||
if (isspace16(*current)) {
|
||||
|
||||
@@ -162,6 +162,7 @@ private:
|
||||
std::u16string mStr;
|
||||
bool mQuote = false;
|
||||
bool mTrailingSpace = false;
|
||||
bool mLastCharWasEscape = false;
|
||||
std::string mError;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@ TEST(UtilTest, StringStartsWith) {
|
||||
EXPECT_TRUE(util::stringStartsWith<char>("hello.xml", "he"));
|
||||
}
|
||||
|
||||
TEST(UtilTest, StringBuilderSplitEscapeSequence) {
|
||||
EXPECT_EQ(StringPiece16(u"this is a new\nline."),
|
||||
util::StringBuilder().append(u"this is a new\\")
|
||||
.append(u"nline.")
|
||||
.str());
|
||||
}
|
||||
|
||||
TEST(UtilTest, StringBuilderWhitespaceRemoval) {
|
||||
EXPECT_EQ(StringPiece16(u"hey guys this is so cool"),
|
||||
util::StringBuilder().append(u" hey guys ")
|
||||
|
||||
Reference in New Issue
Block a user