|
|
|
@ -30,6 +30,8 @@ |
|
|
|
|
|
|
|
|
|
#include <google/protobuf/util/internal/json_stream_parser.h> |
|
|
|
|
|
|
|
|
|
#include <cstdint> |
|
|
|
|
|
|
|
|
|
#include <google/protobuf/stubs/logging.h> |
|
|
|
|
#include <google/protobuf/stubs/common.h> |
|
|
|
|
#include <google/protobuf/util/internal/expecting_objectwriter.h> |
|
|
|
@ -42,11 +44,11 @@ |
|
|
|
|
namespace google { |
|
|
|
|
namespace protobuf { |
|
|
|
|
namespace util { |
|
|
|
|
namespace error { |
|
|
|
|
using util::error::INVALID_ARGUMENT; |
|
|
|
|
} // namespace error
|
|
|
|
|
namespace converter { |
|
|
|
|
|
|
|
|
|
using ParseErrorType = |
|
|
|
|
::google::protobuf::util::converter::JsonStreamParser::ParseErrorType; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Tests for the JSON Stream Parser. These tests are intended to be
|
|
|
|
|
// comprehensive and cover the following:
|
|
|
|
@ -141,6 +143,17 @@ class JsonStreamParserTest : public ::testing::Test { |
|
|
|
|
EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DoErrorTest( |
|
|
|
|
StringPiece json, int split, StringPiece error_prefix, |
|
|
|
|
ParseErrorType expected_parse_error_type, |
|
|
|
|
std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) { |
|
|
|
|
}) { |
|
|
|
|
util::Status result = RunTest(json, split, setup); |
|
|
|
|
EXPECT_EQ(util::error::INVALID_ARGUMENT, result.code()); |
|
|
|
|
StringPiece error_message(result.error_message()); |
|
|
|
|
EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _MSC_VER |
|
|
|
|
// TODO(xiaofeng): We have to disable InSequence check for MSVC because it
|
|
|
|
@ -233,7 +246,7 @@ TEST_F(JsonStreamParserTest, SimpleInt) { |
|
|
|
|
TEST_F(JsonStreamParserTest, SimpleNegativeInt) { |
|
|
|
|
StringPiece str = "-79497823553162765"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.RenderInt64("", int64{-79497823553162765}); |
|
|
|
|
ow_.RenderInt64("", int64_t{-79497823553162765}); |
|
|
|
|
DoTest(str, i); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -241,7 +254,7 @@ TEST_F(JsonStreamParserTest, SimpleNegativeInt) { |
|
|
|
|
TEST_F(JsonStreamParserTest, SimpleUnsignedInt) { |
|
|
|
|
StringPiece str = "11779497823553162765"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.RenderUint64("", uint64{11779497823553162765u}); |
|
|
|
|
ow_.RenderUint64("", uint64_t{11779497823553162765u}); |
|
|
|
|
DoTest(str, i); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -249,26 +262,31 @@ TEST_F(JsonStreamParserTest, SimpleUnsignedInt) { |
|
|
|
|
TEST_F(JsonStreamParserTest, OctalNumberIsInvalid) { |
|
|
|
|
StringPiece str = "01234"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values."); |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.", |
|
|
|
|
ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); |
|
|
|
|
} |
|
|
|
|
str = "-01234"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values."); |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.", |
|
|
|
|
ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, HexNumberIsInvalid) { |
|
|
|
|
StringPiece str = "0x1234"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values."); |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.", |
|
|
|
|
ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); |
|
|
|
|
} |
|
|
|
|
str = "-0x1234"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values."); |
|
|
|
|
DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.", |
|
|
|
|
ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES); |
|
|
|
|
} |
|
|
|
|
str = "12x34"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number."); |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number.", |
|
|
|
|
ParseErrorType::UNABLE_TO_PARSE_NUMBER); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -338,14 +356,16 @@ TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithReservedPrefxes) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithReservedKeyword) { |
|
|
|
|
StringPiece str = "{ null: \"a\", true: \"b\", false: \"c\"}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithEmbeddedNonAlphanumeric) { |
|
|
|
|
StringPiece str = "{ foo-bar-baz: \"a\"}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair."); |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair.", |
|
|
|
|
ParseErrorType::EXPECTED_COLON); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -376,7 +396,7 @@ TEST_F(JsonStreamParserTest, ArrayComplexValues) { |
|
|
|
|
->RenderInt64("", -127) |
|
|
|
|
->RenderDouble("", 45.3) |
|
|
|
|
->RenderDouble("", -1056.4) |
|
|
|
|
->RenderUint64("", uint64{11779497823553162765u}) |
|
|
|
|
->RenderUint64("", uint64_t{11779497823553162765u}) |
|
|
|
|
->EndList() |
|
|
|
|
->StartObject("") |
|
|
|
|
->RenderBool("key", true) |
|
|
|
@ -404,7 +424,7 @@ TEST_F(JsonStreamParserTest, ObjectValues) { |
|
|
|
|
->RenderInt64("ni", -127) |
|
|
|
|
->RenderDouble("pd", 45.3) |
|
|
|
|
->RenderDouble("nd", -1056.4) |
|
|
|
|
->RenderUint64("pl", uint64{11779497823553162765u}) |
|
|
|
|
->RenderUint64("pl", uint64_t{11779497823553162765u}) |
|
|
|
|
->StartList("l") |
|
|
|
|
->StartList("") |
|
|
|
|
->EndList() |
|
|
|
@ -421,13 +441,16 @@ TEST_F(JsonStreamParserTest, ObjectValues) { |
|
|
|
|
TEST_F(JsonStreamParserTest, RejectNonUtf8WhenNotCoerced) { |
|
|
|
|
StringPiece json = "{\"address\":\xFF\"חרושת 23, רעננה, ישראל\"}"; |
|
|
|
|
for (int i = 0; i <= json.length(); ++i) { |
|
|
|
|
DoErrorTest(json, i, "Encountered non UTF-8 code points."); |
|
|
|
|
DoErrorTest(json, i, "Encountered non UTF-8 code points.", |
|
|
|
|
ParseErrorType::NON_UTF_8); |
|
|
|
|
} |
|
|
|
|
json = "{\"address\": \"חרושת 23,\xFFרעננה, ישראל\"}"; |
|
|
|
|
for (int i = 0; i <= json.length(); ++i) { |
|
|
|
|
DoErrorTest(json, i, "Encountered non UTF-8 code points."); |
|
|
|
|
DoErrorTest(json, i, "Encountered non UTF-8 code points.", |
|
|
|
|
ParseErrorType::NON_UTF_8); |
|
|
|
|
} |
|
|
|
|
DoErrorTest("\xFF{}", 0, "Encountered non UTF-8 code points."); |
|
|
|
|
DoErrorTest("\xFF{}", 0, "Encountered non UTF-8 code points.", |
|
|
|
|
ParseErrorType::NON_UTF_8); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// - unicode handling in strings
|
|
|
|
@ -460,7 +483,8 @@ TEST_F(JsonStreamParserTest, UnicodeEscapingInvalidCodePointWhenNotCoerced) { |
|
|
|
|
// A low surrogate alone.
|
|
|
|
|
StringPiece str = "[\"\\ude36\"]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid unicode code point."); |
|
|
|
|
DoErrorTest(str, i, "Invalid unicode code point.", |
|
|
|
|
ParseErrorType::INVALID_UNICODE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -468,22 +492,26 @@ TEST_F(JsonStreamParserTest, UnicodeEscapingMissingLowSurrogateWhenNotCoerced) { |
|
|
|
|
// A high surrogate alone.
|
|
|
|
|
StringPiece str = "[\"\\ud83d\"]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Missing low surrogate."); |
|
|
|
|
DoErrorTest(str, i, "Missing low surrogate.", |
|
|
|
|
ParseErrorType::MISSING_LOW_SURROGATE); |
|
|
|
|
} |
|
|
|
|
// A high surrogate with some trailing characters.
|
|
|
|
|
str = "[\"\\ud83d|ude36\"]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Missing low surrogate."); |
|
|
|
|
DoErrorTest(str, i, "Missing low surrogate.", |
|
|
|
|
ParseErrorType::MISSING_LOW_SURROGATE); |
|
|
|
|
} |
|
|
|
|
// A high surrogate with half a low surrogate.
|
|
|
|
|
str = "[\"\\ud83d\\ude--\"]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence."); |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence.", |
|
|
|
|
ParseErrorType::INVALID_ESCAPE_SEQUENCE); |
|
|
|
|
} |
|
|
|
|
// Two high surrogates.
|
|
|
|
|
str = "[\"\\ud83d\\ud83d\"]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid low surrogate."); |
|
|
|
|
DoErrorTest(str, i, "Invalid low surrogate.", |
|
|
|
|
ParseErrorType::INVALID_LOW_SURROGATE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -527,21 +555,24 @@ TEST_F(JsonStreamParserTest, ExtraTextAfterTrue) { |
|
|
|
|
StringPiece str = "truee"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.RenderBool("", true); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input."); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input.", |
|
|
|
|
ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, InvalidNumberDashOnly) { |
|
|
|
|
StringPiece str = "-"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number."); |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number.", |
|
|
|
|
ParseErrorType::UNABLE_TO_PARSE_NUMBER); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, InvalidNumberDashName) { |
|
|
|
|
StringPiece str = "-foo"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number."); |
|
|
|
|
DoErrorTest(str, i, "Unable to parse number.", |
|
|
|
|
ParseErrorType::UNABLE_TO_PARSE_NUMBER); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -549,7 +580,7 @@ TEST_F(JsonStreamParserTest, InvalidLiteralInArray) { |
|
|
|
|
StringPiece str = "[nule]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList(""); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token."); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -557,7 +588,8 @@ TEST_F(JsonStreamParserTest, InvalidLiteralInObject) { |
|
|
|
|
StringPiece str = "{123false}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -565,14 +597,16 @@ TEST_F(JsonStreamParserTest, InvalidLiteralInObject) { |
|
|
|
|
TEST_F(JsonStreamParserTest, MismatchedSingleQuotedLiteral) { |
|
|
|
|
StringPiece str = "'Some str\""; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, MismatchedDoubleQuotedLiteral) { |
|
|
|
|
StringPiece str = "\"Another string that ends poorly!'"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -580,14 +614,16 @@ TEST_F(JsonStreamParserTest, MismatchedDoubleQuotedLiteral) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnterminatedLiteralString) { |
|
|
|
|
StringPiece str = "\"Forgot the rest of i"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(JsonStreamParserTest, UnterminatedStringEscape) { |
|
|
|
|
StringPiece str = "\"Forgot the rest of \\"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -595,7 +631,8 @@ TEST_F(JsonStreamParserTest, UnterminatedStringInArray) { |
|
|
|
|
StringPiece str = "[\"Forgot to close the string]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList(""); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -603,7 +640,8 @@ TEST_F(JsonStreamParserTest, UnterminatedStringInObject) { |
|
|
|
|
StringPiece str = "{f: \"Forgot to close the string}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -611,7 +649,8 @@ TEST_F(JsonStreamParserTest, UnterminatedObject) { |
|
|
|
|
StringPiece str = "{"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Unexpected end of string."); |
|
|
|
|
DoErrorTest(str, i, "Unexpected end of string.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -621,7 +660,8 @@ TEST_F(JsonStreamParserTest, MismatchedCloseObject) { |
|
|
|
|
StringPiece str = "{'key': true]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject("")->RenderBool("key", true); |
|
|
|
|
DoErrorTest(str, i, "Expected , or } after key:value pair."); |
|
|
|
|
DoErrorTest(str, i, "Expected , or } after key:value pair.", |
|
|
|
|
ParseErrorType::EXPECTED_COMMA_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -629,7 +669,8 @@ TEST_F(JsonStreamParserTest, MismatchedCloseArray) { |
|
|
|
|
StringPiece str = "[true, null}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList("")->RenderBool("", true)->RenderNull(""); |
|
|
|
|
DoErrorTest(str, i, "Expected , or ] after array value."); |
|
|
|
|
DoErrorTest(str, i, "Expected , or ] after array value.", |
|
|
|
|
ParseErrorType::EXPECTED_COMMA_OR_BRACKET); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -638,7 +679,8 @@ TEST_F(JsonStreamParserTest, InvalidNumericObjectKey) { |
|
|
|
|
StringPiece str = "{42: true}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -646,7 +688,8 @@ TEST_F(JsonStreamParserTest, InvalidLiteralObjectInObject) { |
|
|
|
|
StringPiece str = "{{bob: true}}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -654,7 +697,8 @@ TEST_F(JsonStreamParserTest, InvalidLiteralArrayInObject) { |
|
|
|
|
StringPiece str = "{[null]}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -662,7 +706,8 @@ TEST_F(JsonStreamParserTest, InvalidLiteralValueInObject) { |
|
|
|
|
StringPiece str = "{false}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -670,7 +715,8 @@ TEST_F(JsonStreamParserTest, MissingColonAfterStringInObject) { |
|
|
|
|
StringPiece str = "{\"key\"}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair."); |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair.", |
|
|
|
|
ParseErrorType::EXPECTED_COLON); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -678,7 +724,8 @@ TEST_F(JsonStreamParserTest, MissingColonAfterKeyInObject) { |
|
|
|
|
StringPiece str = "{key}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair."); |
|
|
|
|
DoErrorTest(str, i, "Expected : between key:value pair.", |
|
|
|
|
ParseErrorType::EXPECTED_COLON); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -686,7 +733,8 @@ TEST_F(JsonStreamParserTest, EndOfTextAfterKeyInObject) { |
|
|
|
|
StringPiece str = "{key"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Unexpected end of string."); |
|
|
|
|
DoErrorTest(str, i, "Unexpected end of string.", |
|
|
|
|
ParseErrorType::EXPECTED_COLON); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -694,7 +742,7 @@ TEST_F(JsonStreamParserTest, MissingValueAfterColonInObject) { |
|
|
|
|
StringPiece str = "{key:}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token."); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -702,7 +750,8 @@ TEST_F(JsonStreamParserTest, MissingCommaBetweenObjectEntries) { |
|
|
|
|
StringPiece str = "{key:20 'hello': true}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject("")->RenderUint64("key", 20); |
|
|
|
|
DoErrorTest(str, i, "Expected , or } after key:value pair."); |
|
|
|
|
DoErrorTest(str, i, "Expected , or } after key:value pair.", |
|
|
|
|
ParseErrorType::EXPECTED_COMMA_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -710,7 +759,8 @@ TEST_F(JsonStreamParserTest, InvalidLiteralAsObjectKey) { |
|
|
|
|
StringPiece str = "{false: 20}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -718,7 +768,8 @@ TEST_F(JsonStreamParserTest, ExtraCharactersAfterObject) { |
|
|
|
|
StringPiece str = "{}}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject("")->EndObject(); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input."); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input.", |
|
|
|
|
ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -742,12 +793,14 @@ TEST_F(JsonStreamParserTest, DoubleTooBig) { |
|
|
|
|
StringPiece str = "[1.89769e+308]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList(""); |
|
|
|
|
DoErrorTest(str, i, "Number exceeds the range of double."); |
|
|
|
|
DoErrorTest(str, i, "Number exceeds the range of double.", |
|
|
|
|
ParseErrorType::NUMBER_EXCEEDS_RANGE_DOUBLE); |
|
|
|
|
} |
|
|
|
|
str = "[-1.89769e+308]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList(""); |
|
|
|
|
DoErrorTest(str, i, "Number exceeds the range of double."); |
|
|
|
|
DoErrorTest(str, i, "Number exceeds the range of double.", |
|
|
|
|
ParseErrorType::NUMBER_EXCEEDS_RANGE_DOUBLE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -756,7 +809,8 @@ TEST_F(JsonStreamParserTest, DoubleTooBig) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnfinishedEscape) { |
|
|
|
|
StringPiece str = "\"\\"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string."); |
|
|
|
|
DoErrorTest(str, i, "Closing quote expected in string.", |
|
|
|
|
ParseErrorType::EXPECTED_CLOSING_QUOTE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -764,7 +818,8 @@ TEST_F(JsonStreamParserTest, UnfinishedEscape) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnfinishedUnicodeEscape) { |
|
|
|
|
StringPiece str = "\"\\u"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Illegal hex string."); |
|
|
|
|
DoErrorTest(str, i, "Illegal hex string.", |
|
|
|
|
ParseErrorType::ILLEGAL_HEX_STRING); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -772,7 +827,8 @@ TEST_F(JsonStreamParserTest, UnfinishedUnicodeEscape) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) { |
|
|
|
|
StringPiece str = "\"\\u12"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Illegal hex string."); |
|
|
|
|
DoErrorTest(str, i, "Illegal hex string.", |
|
|
|
|
ParseErrorType::ILLEGAL_HEX_STRING); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -780,7 +836,8 @@ TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) { |
|
|
|
|
TEST_F(JsonStreamParserTest, BracketedUnicodeEscape) { |
|
|
|
|
StringPiece str = "\"\\u{1f36f}\""; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence."); |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence.", |
|
|
|
|
ParseErrorType::INVALID_ESCAPE_SEQUENCE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -788,7 +845,8 @@ TEST_F(JsonStreamParserTest, BracketedUnicodeEscape) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) { |
|
|
|
|
StringPiece str = "\"\\u12$4hello"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence."); |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence.", |
|
|
|
|
ParseErrorType::INVALID_ESCAPE_SEQUENCE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -796,7 +854,8 @@ TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnicodeEscapeLowHalfSurrogateInvalidCharacters) { |
|
|
|
|
StringPiece str = "\"\\ud800\\udcfg\""; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence."); |
|
|
|
|
DoErrorTest(str, i, "Invalid escape sequence.", |
|
|
|
|
ParseErrorType::INVALID_ESCAPE_SEQUENCE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -805,7 +864,8 @@ TEST_F(JsonStreamParserTest, ExtraCommaInObject) { |
|
|
|
|
StringPiece str = "{'k1': true,,'k2': false}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject("")->RenderBool("k1", true); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }."); |
|
|
|
|
DoErrorTest(str, i, "Expected an object key or }.", |
|
|
|
|
ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -813,7 +873,7 @@ TEST_F(JsonStreamParserTest, ExtraCommaInArray) { |
|
|
|
|
StringPiece str = "[true,,false}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList("")->RenderBool("", true); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token."); |
|
|
|
|
DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -822,7 +882,8 @@ TEST_F(JsonStreamParserTest, ExtraTextAfterLiteral) { |
|
|
|
|
StringPiece str = "'hello', 'world'"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.RenderString("", "hello"); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input."); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input.", |
|
|
|
|
ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -830,7 +891,8 @@ TEST_F(JsonStreamParserTest, ExtraTextAfterObject) { |
|
|
|
|
StringPiece str = "{'key': true} 'oops'"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject("")->RenderBool("key", true)->EndObject(); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input."); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input.", |
|
|
|
|
ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -838,7 +900,8 @@ TEST_F(JsonStreamParserTest, ExtraTextAfterArray) { |
|
|
|
|
StringPiece str = "[null] 'oops'"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList("")->RenderNull("")->EndList(); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input."); |
|
|
|
|
DoErrorTest(str, i, "Parsing terminated before end of input.", |
|
|
|
|
ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -846,7 +909,7 @@ TEST_F(JsonStreamParserTest, ExtraTextAfterArray) { |
|
|
|
|
TEST_F(JsonStreamParserTest, UnknownCharactersAsValue) { |
|
|
|
|
StringPiece str = "*"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
DoErrorTest(str, i, "Expected a value."); |
|
|
|
|
DoErrorTest(str, i, "Expected a value.", ParseErrorType::EXPECTED_VALUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -854,7 +917,8 @@ TEST_F(JsonStreamParserTest, UnknownCharactersInArray) { |
|
|
|
|
StringPiece str = "[*]"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartList(""); |
|
|
|
|
DoErrorTest(str, i, "Expected a value or ] within an array."); |
|
|
|
|
DoErrorTest(str, i, "Expected a value or ] within an array.", |
|
|
|
|
ParseErrorType::EXPECTED_VALUE_OR_BRACKET); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -862,7 +926,7 @@ TEST_F(JsonStreamParserTest, UnknownCharactersInObject) { |
|
|
|
|
StringPiece str = "{'key': *}"; |
|
|
|
|
for (int i = 0; i <= str.length(); ++i) { |
|
|
|
|
ow_.StartObject(""); |
|
|
|
|
DoErrorTest(str, i, "Expected a value."); |
|
|
|
|
DoErrorTest(str, i, "Expected a value.", ParseErrorType::EXPECTED_VALUE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|