Commit a31c717d authored by Jonathon Kereliuk's avatar Jonathon Kereliuk Committed by Commit Bot

Replace invalid UTF-16 escape sequences

when decoding invalid UTF strings in chromedriver.

Web platform tests use ECMAScript strings which
aren't necessarily utf-16 characters.
This change will help us deal with that case.

More info: 
https://bugs.chromium.org/p/chromium/issues/detail?id=723592

To reproduce the error message from above, run:

./wptrun chrome url/url-constructor.html

on web platform tests.

Bug: 723592
Change-Id: Icf4b7de968ace81abba9f3020b9c123ab0791318
Reviewed-on: https://chromium-review.googlesource.com/565461
Commit-Queue: Jonathon Kereliuk <kereliuk@chromium.org>
Reviewed-by: default avatarJohn Budorick <jbudorick@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487152}
parent 01c769a6
...@@ -667,8 +667,13 @@ bool JSONParser::DecodeUTF16(std::string* dest_string) { ...@@ -667,8 +667,13 @@ bool JSONParser::DecodeUTF16(std::string* dest_string) {
} else { } else {
// Not a surrogate. // Not a surrogate.
DCHECK(CBU16_IS_SINGLE(code_unit16_high)); DCHECK(CBU16_IS_SINGLE(code_unit16_high));
if (!IsValidCharacter(code_unit16_high)) if (!IsValidCharacter(code_unit16_high)) {
return false; if ((options_ & JSON_REPLACE_INVALID_CHARACTERS) == 0) {
return false;
}
dest_string->append(kUnicodeReplacementString);
return true;
}
CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high);
} }
......
...@@ -260,6 +260,7 @@ class BASE_EXPORT JSONParser { ...@@ -260,6 +260,7 @@ class BASE_EXPORT JSONParser {
FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeNumbers); FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ConsumeNumbers);
FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ErrorMessages); FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ErrorMessages);
FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ReplaceInvalidCharacters); FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ReplaceInvalidCharacters);
FRIEND_TEST_ALL_PREFIXES(JSONParserTest, ReplaceInvalidUTF16EscapeSequence);
DISALLOW_COPY_AND_ASSIGN(JSONParser); DISALLOW_COPY_AND_ASSIGN(JSONParser);
}; };
......
...@@ -315,6 +315,12 @@ TEST_F(JSONParserTest, ErrorMessages) { ...@@ -315,6 +315,12 @@ TEST_F(JSONParserTest, ErrorMessages) {
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape), EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
error_message); error_message);
EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code); EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
root = JSONReader::ReadAndReturnError(("[\"\\ufffe\"]"), JSON_PARSE_RFC,
&error_code, &error_message);
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
error_message);
EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
} }
TEST_F(JSONParserTest, Decode4ByteUtf8Char) { TEST_F(JSONParserTest, Decode4ByteUtf8Char) {
...@@ -335,6 +341,11 @@ TEST_F(JSONParserTest, DecodeUnicodeNonCharacter) { ...@@ -335,6 +341,11 @@ TEST_F(JSONParserTest, DecodeUnicodeNonCharacter) {
EXPECT_FALSE(JSONReader::Read("[\"\\ufdd0\"]")); EXPECT_FALSE(JSONReader::Read("[\"\\ufdd0\"]"));
EXPECT_FALSE(JSONReader::Read("[\"\\ufffe\"]")); EXPECT_FALSE(JSONReader::Read("[\"\\ufffe\"]"));
EXPECT_FALSE(JSONReader::Read("[\"\\ud83f\\udffe\"]")); EXPECT_FALSE(JSONReader::Read("[\"\\ud83f\\udffe\"]"));
EXPECT_TRUE(
JSONReader::Read("[\"\\ufdd0\"]", JSON_REPLACE_INVALID_CHARACTERS));
EXPECT_TRUE(
JSONReader::Read("[\"\\ufffe\"]", JSON_REPLACE_INVALID_CHARACTERS));
} }
TEST_F(JSONParserTest, DecodeNegativeEscapeSequence) { TEST_F(JSONParserTest, DecodeNegativeEscapeSequence) {
...@@ -355,6 +366,17 @@ TEST_F(JSONParserTest, ReplaceInvalidCharacters) { ...@@ -355,6 +366,17 @@ TEST_F(JSONParserTest, ReplaceInvalidCharacters) {
EXPECT_EQ(kUnicodeReplacementString, str); EXPECT_EQ(kUnicodeReplacementString, str);
} }
TEST_F(JSONParserTest, ReplaceInvalidUTF16EscapeSequence) {
const std::string invalid = "\"\\ufffe\"";
std::unique_ptr<JSONParser> parser(
NewTestParser(invalid, JSON_REPLACE_INVALID_CHARACTERS));
std::unique_ptr<Value> value(parser->ConsumeString());
ASSERT_TRUE(value.get());
std::string str;
EXPECT_TRUE(value->GetAsString(&str));
EXPECT_EQ(kUnicodeReplacementString, str);
}
TEST_F(JSONParserTest, ParseNumberErrors) { TEST_F(JSONParserTest, ParseNumberErrors) {
const struct { const struct {
const char* input; const char* input;
......
...@@ -504,7 +504,10 @@ bool ParseInspectorMessage( ...@@ -504,7 +504,10 @@ bool ParseInspectorMessage(
InspectorMessageType* type, InspectorMessageType* type,
InspectorEvent* event, InspectorEvent* event,
InspectorCommandResponse* command_response) { InspectorCommandResponse* command_response) {
std::unique_ptr<base::Value> message_value = base::JSONReader::Read(message); // We want to allow invalid characters in case they are valid ECMAScript
// strings. For example, webplatform tests use this to check string handling
std::unique_ptr<base::Value> message_value =
base::JSONReader::Read(message, base::JSON_REPLACE_INVALID_CHARACTERS);
base::DictionaryValue* message_dict; base::DictionaryValue* message_dict;
if (!message_value || !message_value->GetAsDictionary(&message_dict)) if (!message_value || !message_value->GetAsDictionary(&message_dict))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment