| Index: base/json/json_reader_unittest.cc
|
| diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
|
| index 4d6b0c4edf595103a5bec62138c1a9d4586ae26a..38bf590695c5eb38930396418502de8c640e7d5a 100644
|
| --- a/base/json/json_reader_unittest.cc
|
| +++ b/base/json/json_reader_unittest.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/base_paths.h"
|
| #include "base/file_util.h"
|
| +#include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/path_service.h"
|
| #include "base/string_piece.h"
|
| @@ -19,56 +20,67 @@ namespace base {
|
| TEST(JSONReaderTest, Reading) {
|
| // some whitespace checking
|
| scoped_ptr<Value> root;
|
| - root.reset(JSONReader().JsonToValue(" null ", false, false));
|
| + root.reset(JSONReader().ReadToValue(" null "));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
|
|
|
| // Invalid JSON string
|
| - root.reset(JSONReader().JsonToValue("nu", false, false));
|
| + root.reset(JSONReader().ReadToValue("nu"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Simple bool
|
| - root.reset(JSONReader().JsonToValue("true ", false, false));
|
| + root.reset(JSONReader().ReadToValue("true "));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN));
|
|
|
| // Embedded comment
|
| - root.reset(JSONReader().JsonToValue("/* comment */null", false, false));
|
| + root.reset(JSONReader().ReadToValue("/* comment */null"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
|
| - root.reset(JSONReader().JsonToValue("40 /* comment */", false, false));
|
| + root.reset(JSONReader().ReadToValue("40 /* comment */"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
|
| - root.reset(JSONReader().JsonToValue("true // comment", false, false));
|
| + root.reset(JSONReader().ReadToValue("true // comment"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN));
|
| - root.reset(JSONReader().JsonToValue("/* comment */\"sample string\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("/* comment */\"sample string\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| std::string value;
|
| EXPECT_TRUE(root->GetAsString(&value));
|
| EXPECT_EQ("sample string", value);
|
| + root.reset(JSONReader().ReadToValue("[1, /* comment, 2 ] */ \n 3]"));
|
| + ASSERT_TRUE(root.get());
|
| + ListValue* list = static_cast<ListValue*>(root.get());
|
| + EXPECT_EQ(2u, list->GetSize());
|
| + int int_val = 0;
|
| + EXPECT_TRUE(list->GetInteger(0, &int_val));
|
| + EXPECT_EQ(1, int_val);
|
| + EXPECT_TRUE(list->GetInteger(1, &int_val));
|
| + EXPECT_EQ(3, int_val);
|
| + root.reset(JSONReader().ReadToValue("[1, /*a*/2, 3]"));
|
| + ASSERT_TRUE(root.get());
|
| + list = static_cast<ListValue*>(root.get());
|
| + EXPECT_EQ(3u, list->GetSize());
|
|
|
| // Test number formats
|
| - root.reset(JSONReader().JsonToValue("43", false, false));
|
| + root.reset(JSONReader().ReadToValue("43"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
|
| - int int_val = 0;
|
| EXPECT_TRUE(root->GetAsInteger(&int_val));
|
| EXPECT_EQ(43, int_val);
|
|
|
| // According to RFC4627, oct, hex, and leading zeros are invalid JSON.
|
| - root.reset(JSONReader().JsonToValue("043", false, false));
|
| + root.reset(JSONReader().ReadToValue("043"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("0x43", false, false));
|
| + root.reset(JSONReader().ReadToValue("0x43"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("00", false, false));
|
| + root.reset(JSONReader().ReadToValue("00"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Test 0 (which needs to be special cased because of the leading zero
|
| // clause).
|
| - root.reset(JSONReader().JsonToValue("0", false, false));
|
| + root.reset(JSONReader().ReadToValue("0"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
|
| int_val = 1;
|
| @@ -77,14 +89,14 @@ TEST(JSONReaderTest, Reading) {
|
|
|
| // Numbers that overflow ints should succeed, being internally promoted to
|
| // storage as doubles
|
| - root.reset(JSONReader().JsonToValue("2147483648", false, false));
|
| + root.reset(JSONReader().ReadToValue("2147483648"));
|
| ASSERT_TRUE(root.get());
|
| double double_val;
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(2147483648.0, double_val);
|
| - root.reset(JSONReader().JsonToValue("-2147483649", false, false));
|
| + root.reset(JSONReader().ReadToValue("-2147483649"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| @@ -92,42 +104,42 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_DOUBLE_EQ(-2147483649.0, double_val);
|
|
|
| // Parse a double
|
| - root.reset(JSONReader().JsonToValue("43.1", false, false));
|
| + root.reset(JSONReader().ReadToValue("43.1"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(43.1, double_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("4.3e-1", false, false));
|
| + root.reset(JSONReader().ReadToValue("4.3e-1"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(.43, double_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("2.1e0", false, false));
|
| + root.reset(JSONReader().ReadToValue("2.1e0"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(2.1, double_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("2.1e+0001", false, false));
|
| + root.reset(JSONReader().ReadToValue("2.1e+0001"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(21.0, double_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("0.01", false, false));
|
| + root.reset(JSONReader().ReadToValue("0.01"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| EXPECT_TRUE(root->GetAsDouble(&double_val));
|
| EXPECT_DOUBLE_EQ(0.01, double_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("1.00", false, false));
|
| + root.reset(JSONReader().ReadToValue("1.00"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
|
| double_val = 0.0;
|
| @@ -135,43 +147,43 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_DOUBLE_EQ(1.0, double_val);
|
|
|
| // Fractional parts must have a digit before and after the decimal point.
|
| - root.reset(JSONReader().JsonToValue("1.", false, false));
|
| + root.reset(JSONReader().ReadToValue("1."));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue(".1", false, false));
|
| + root.reset(JSONReader().ReadToValue(".1"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("1.e10", false, false));
|
| + root.reset(JSONReader().ReadToValue("1.e10"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Exponent must have a digit following the 'e'.
|
| - root.reset(JSONReader().JsonToValue("1e", false, false));
|
| + root.reset(JSONReader().ReadToValue("1e"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("1E", false, false));
|
| + root.reset(JSONReader().ReadToValue("1E"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("1e1.", false, false));
|
| + root.reset(JSONReader().ReadToValue("1e1."));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("1e1.0", false, false));
|
| + root.reset(JSONReader().ReadToValue("1e1.0"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // INF/-INF/NaN are not valid
|
| - root.reset(JSONReader().JsonToValue("1e1000", false, false));
|
| + root.reset(JSONReader().ReadToValue("1e1000"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("-1e1000", false, false));
|
| + root.reset(JSONReader().ReadToValue("-1e1000"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("NaN", false, false));
|
| + root.reset(JSONReader().ReadToValue("NaN"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("nan", false, false));
|
| + root.reset(JSONReader().ReadToValue("nan"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("inf", false, false));
|
| + root.reset(JSONReader().ReadToValue("inf"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Invalid number formats
|
| - root.reset(JSONReader().JsonToValue("4.3.1", false, false));
|
| + root.reset(JSONReader().ReadToValue("4.3.1"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("4e3.1", false, false));
|
| + root.reset(JSONReader().ReadToValue("4e3.1"));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Test string parser
|
| - root.reset(JSONReader().JsonToValue("\"hello world\"", false, false));
|
| + root.reset(JSONReader().ReadToValue("\"hello world\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| std::string str_val;
|
| @@ -179,7 +191,7 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_EQ("hello world", str_val);
|
|
|
| // Empty string
|
| - root.reset(JSONReader().JsonToValue("\"\"", false, false));
|
| + root.reset(JSONReader().ReadToValue("\"\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| @@ -187,8 +199,7 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_EQ("", str_val);
|
|
|
| // Test basic string escapes
|
| - root.reset(JSONReader().JsonToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| @@ -196,8 +207,7 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_EQ(" \"\\/\b\f\n\r\t\v", str_val);
|
|
|
| // Test hex and unicode escapes including the null character.
|
| - root.reset(JSONReader().JsonToValue("\"\\x41\\x00\\u1234\"", false,
|
| - false));
|
| + root.reset(JSONReader().ReadToValue("\"\\x41\\x00\\u1234\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| @@ -205,29 +215,24 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_EQ(std::wstring(L"A\0\x1234", 3), UTF8ToWide(str_val));
|
|
|
| // Test invalid strings
|
| - root.reset(JSONReader().JsonToValue("\"no closing quote", false, false));
|
| + root.reset(JSONReader().ReadToValue("\"no closing quote"));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("\"\\z invalid escape char\"", false,
|
| - false));
|
| + root.reset(JSONReader().ReadToValue("\"\\z invalid escape char\""));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("\"\\xAQ invalid hex code\"", false,
|
| - false));
|
| + root.reset(JSONReader().ReadToValue("\"\\xAQ invalid hex code\""));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("not enough hex chars\\x1\"", false,
|
| - false));
|
| + root.reset(JSONReader().ReadToValue("not enough hex chars\\x1\""));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("\"not enough escape chars\\u123\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"not enough escape chars\\u123\""));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("\"extra backslash at end of input\\\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"extra backslash at end of input\\\""));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Basic array
|
| root.reset(JSONReader::Read("[true, false, null]"));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
|
| - ListValue* list = static_cast<ListValue*>(root.get());
|
| + list = static_cast<ListValue*>(root.get());
|
| EXPECT_EQ(3U, list->GetSize());
|
|
|
| // Test with trailing comma. Should be parsed the same as above.
|
| @@ -448,32 +453,38 @@ TEST(JSONReaderTest, Reading) {
|
| EXPECT_EQ(5001U, list->GetSize());
|
|
|
| // Test utf8 encoded input
|
| - root.reset(JSONReader().JsonToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| EXPECT_TRUE(root->GetAsString(&str_val));
|
| EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val));
|
|
|
| + root.reset(JSONReader().ReadToValue(
|
| + "{\"path\": \"/tmp/\xc3\xa0\xc3\xa8\xc3\xb2.png\"}"));
|
| + ASSERT_TRUE(root.get());
|
| + EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
|
| + EXPECT_TRUE(root->GetAsDictionary(&dict_val));
|
| + EXPECT_TRUE(dict_val->GetString("path", &str_val));
|
| + EXPECT_EQ("/tmp/\xC3\xA0\xC3\xA8\xC3\xB2.png", str_val);
|
| +
|
| // Test invalid utf8 encoded input
|
| - root.reset(JSONReader().JsonToValue("\"345\xb0\xa1\xb0\xa2\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"345\xb0\xa1\xb0\xa2\""));
|
| + EXPECT_FALSE(root.get());
|
| + root.reset(JSONReader().ReadToValue("\"123\xc0\x81\""));
|
| EXPECT_FALSE(root.get());
|
| - root.reset(JSONReader().JsonToValue("\"123\xc0\x81\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"abc\xc0\xae\""));
|
| EXPECT_FALSE(root.get());
|
|
|
| // Test utf16 encoded strings.
|
| - root.reset(JSONReader().JsonToValue("\"\\u20ac3,14\"", false, false));
|
| + root.reset(JSONReader().ReadToValue("\"\\u20ac3,14\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| EXPECT_TRUE(root->GetAsString(&str_val));
|
| EXPECT_EQ("\xe2\x82\xac""3,14", str_val);
|
|
|
| - root.reset(JSONReader().JsonToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\"",
|
| - false, false));
|
| + root.reset(JSONReader().ReadToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\""));
|
| ASSERT_TRUE(root.get());
|
| EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
|
| str_val.clear();
|
| @@ -492,9 +503,28 @@ TEST(JSONReaderTest, Reading) {
|
| "\"\\ud83\\foo\"" // No lower surrogate.
|
| };
|
| for (size_t i = 0; i < arraysize(cases); ++i) {
|
| - root.reset(JSONReader().JsonToValue(cases[i], false, false));
|
| + root.reset(JSONReader().ReadToValue(cases[i]));
|
| EXPECT_FALSE(root.get()) << cases[i];
|
| }
|
| +
|
| + // Test literal root objects.
|
| + root.reset(JSONReader::Read("null"));
|
| + EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
|
| +
|
| + root.reset(JSONReader::Read("true"));
|
| + ASSERT_TRUE(root.get());
|
| + EXPECT_TRUE(root->GetAsBoolean(&bool_value));
|
| + EXPECT_TRUE(bool_value);
|
| +
|
| + root.reset(JSONReader::Read("10"));
|
| + ASSERT_TRUE(root.get());
|
| + EXPECT_TRUE(root->GetAsInteger(&integer_value));
|
| + EXPECT_EQ(10, integer_value);
|
| +
|
| + root.reset(JSONReader::Read("\"root\""));
|
| + ASSERT_TRUE(root.get());
|
| + EXPECT_TRUE(root->GetAsString(&str_val));
|
| + EXPECT_EQ("root", str_val);
|
| }
|
|
|
| TEST(JSONReaderTest, ReadFromFile) {
|
| @@ -509,102 +539,110 @@ TEST(JSONReaderTest, ReadFromFile) {
|
| path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input));
|
|
|
| JSONReader reader;
|
| - std::string error_msg;
|
| - scoped_ptr<Value> root(
|
| - JSONReader::ReadAndReturnError(input, JSON_PARSE_RFC, NULL, &error_msg));
|
| + scoped_ptr<Value> root(reader.ReadToValue(input));
|
| ASSERT_TRUE(root.get()) << reader.GetErrorMessage();
|
| EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
|
| }
|
|
|
| -TEST(JSONReaderTest, ErrorMessages) {
|
| - // Error strings should not be modified in case of success.
|
| - std::string error_message;
|
| - int error_code = 0;
|
| - scoped_ptr<Value> root;
|
| - root.reset(JSONReader::ReadAndReturnError("[42]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_TRUE(error_message.empty());
|
| - EXPECT_EQ(0, error_code);
|
| -
|
| - // Test line and column counting
|
| - const char* big_json = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]";
|
| - // error here --------------------------------^
|
| - root.reset(JSONReader::ReadAndReturnError(big_json, JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(5, 9, JSONReader::kSyntaxError),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
|
| -
|
| - // Test each of the error conditions
|
| - root.reset(JSONReader::ReadAndReturnError("{},{}", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 3,
|
| - JSONReader::kUnexpectedDataAfterRoot), error_message);
|
| - EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, error_code);
|
| -
|
| - std::string nested_json;
|
| - for (int i = 0; i < 101; ++i) {
|
| - nested_json.insert(nested_json.begin(), '[');
|
| - nested_json.append(1, ']');
|
| +// Tests that the root of a JSON object can be deleted safely while its
|
| +// children outlive it.
|
| +TEST(JSONReaderTest, StringOptimizations) {
|
| + Value* dict_literals[2] = {0};
|
| + Value* dict_strings[2] = {0};
|
| + Value* list_values[2] = {0};
|
| +
|
| + {
|
| + scoped_ptr<Value> root(JSONReader::Read(
|
| + "{"
|
| + " \"test\": {"
|
| + " \"foo\": true,"
|
| + " \"bar\": 3.14,"
|
| + " \"baz\": \"bat\","
|
| + " \"moo\": \"cow\""
|
| + " },"
|
| + " \"list\": ["
|
| + " \"a\","
|
| + " \"b\""
|
| + " ]"
|
| + "}", JSON_DETACHABLE_CHILDREN));
|
| + ASSERT_TRUE(root.get());
|
| +
|
| + DictionaryValue* root_dict = NULL;
|
| + ASSERT_TRUE(root->GetAsDictionary(&root_dict));
|
| +
|
| + DictionaryValue* dict = NULL;
|
| + ListValue* list = NULL;
|
| +
|
| + ASSERT_TRUE(root_dict->GetDictionary("test", &dict));
|
| + ASSERT_TRUE(root_dict->GetList("list", &list));
|
| +
|
| + EXPECT_TRUE(dict->Remove("foo", &dict_literals[0]));
|
| + EXPECT_TRUE(dict->Remove("bar", &dict_literals[1]));
|
| + EXPECT_TRUE(dict->Remove("baz", &dict_strings[0]));
|
| + EXPECT_TRUE(dict->Remove("moo", &dict_strings[1]));
|
| +
|
| + ASSERT_EQ(2u, list->GetSize());
|
| + EXPECT_TRUE(list->Remove(0, &list_values[0]));
|
| + EXPECT_TRUE(list->Remove(0, &list_values[1]));
|
| }
|
| - root.reset(JSONReader::ReadAndReturnError(nested_json, JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 101, JSONReader::kTooMuchNesting),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_TOO_MUCH_NESTING, error_code);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("[1,]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 4, JSONReader::kTrailingComma),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code);
|
| + bool b = false;
|
| + double d = 0;
|
| + std::string s;
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("{foo:\"bar\"}", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2,
|
| - JSONReader::kUnquotedDictionaryKey), error_message);
|
| - EXPECT_EQ(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, error_code);
|
| + EXPECT_TRUE(dict_literals[0]->GetAsBoolean(&b));
|
| + EXPECT_TRUE(b);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}",
|
| - JSON_PARSE_RFC,
|
| - &error_code,
|
| - &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 14, JSONReader::kTrailingComma),
|
| - error_message);
|
| + EXPECT_TRUE(dict_literals[1]->GetAsDouble(&d));
|
| + EXPECT_EQ(3.14, d);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("[nu]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2, JSONReader::kSyntaxError),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
|
| + EXPECT_TRUE(dict_strings[0]->GetAsString(&s));
|
| + EXPECT_EQ("bat", s);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
|
| + EXPECT_TRUE(dict_strings[1]->GetAsString(&s));
|
| + EXPECT_EQ("cow", s);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
|
| + EXPECT_TRUE(list_values[0]->GetAsString(&s));
|
| + EXPECT_EQ("a", s);
|
| + EXPECT_TRUE(list_values[1]->GetAsString(&s));
|
| + EXPECT_EQ("b", s);
|
|
|
| - root.reset(JSONReader::ReadAndReturnError("[\"xxx\\q\"]", JSON_PARSE_RFC,
|
| - &error_code, &error_message));
|
| - EXPECT_FALSE(root.get());
|
| - EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
|
| - error_message);
|
| - EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
|
| + delete dict_literals[0];
|
| + delete dict_literals[1];
|
| + delete dict_strings[0];
|
| + delete dict_strings[1];
|
| + delete list_values[0];
|
| + delete list_values[1];
|
| +}
|
| +
|
| +// A smattering of invalid JSON designed to test specific portions of the
|
| +// parser implementation against buffer overflow. Best run with DCHECKs so
|
| +// that the one in NextChar fires.
|
| +TEST(JSONReaderTest, InvalidSanity) {
|
| + const char* invalid_json[] = {
|
| + "/* test *",
|
| + "{\"foo\"",
|
| + "{\"foo\":",
|
| + " [",
|
| + "\"\\u123g\"",
|
| + "{\n\"eh:\n}",
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(invalid_json); ++i) {
|
| + JSONReader reader;
|
| + LOG(INFO) << "Sanity test " << i << ": <" << invalid_json[i] << ">";
|
| + EXPECT_FALSE(reader.ReadToValue(invalid_json[i]));
|
| + EXPECT_NE(JSONReader::JSON_NO_ERROR, reader.error_code());
|
| + EXPECT_NE("", reader.GetErrorMessage());
|
| + }
|
| +}
|
| +
|
| +TEST(JSONReaderTest, IllegalTrailingNull) {
|
| + const char json[] = { '"', 'n', 'u', 'l', 'l', '"', '\0' };
|
| + std::string json_string(json, sizeof(json));
|
| + JSONReader reader;
|
| + EXPECT_FALSE(reader.ReadToValue(json_string));
|
| + EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, reader.error_code());
|
| }
|
|
|
| } // namespace base
|
|
|