| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/json/json_reader.h" | |
| 6 | |
| 7 #include "base/base_paths.h" | |
| 8 #include "base/files/file_util.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/path_service.h" | |
| 12 #include "base/strings/string_piece.h" | |
| 13 #include "base/strings/utf_string_conversions.h" | |
| 14 #include "base/values.h" | |
| 15 #include "build/build_config.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 namespace base { | |
| 19 | |
| 20 TEST(JSONReaderTest, Reading) { | |
| 21 // some whitespace checking | |
| 22 scoped_ptr<Value> root; | |
| 23 root = JSONReader().ReadToValue(" null "); | |
| 24 ASSERT_TRUE(root.get()); | |
| 25 EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | |
| 26 | |
| 27 // Invalid JSON string | |
| 28 root = JSONReader().ReadToValue("nu"); | |
| 29 EXPECT_FALSE(root.get()); | |
| 30 | |
| 31 // Simple bool | |
| 32 root = JSONReader().ReadToValue("true "); | |
| 33 ASSERT_TRUE(root.get()); | |
| 34 EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | |
| 35 | |
| 36 // Embedded comment | |
| 37 root = JSONReader().ReadToValue("/* comment */null"); | |
| 38 ASSERT_TRUE(root.get()); | |
| 39 EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | |
| 40 root = JSONReader().ReadToValue("40 /* comment */"); | |
| 41 ASSERT_TRUE(root.get()); | |
| 42 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | |
| 43 root = JSONReader().ReadToValue("true // comment"); | |
| 44 ASSERT_TRUE(root.get()); | |
| 45 EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | |
| 46 root = JSONReader().ReadToValue("/* comment */\"sample string\""); | |
| 47 ASSERT_TRUE(root.get()); | |
| 48 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 49 std::string value; | |
| 50 EXPECT_TRUE(root->GetAsString(&value)); | |
| 51 EXPECT_EQ("sample string", value); | |
| 52 root = JSONReader().ReadToValue("[1, /* comment, 2 ] */ \n 3]"); | |
| 53 ASSERT_TRUE(root.get()); | |
| 54 ListValue* list = static_cast<ListValue*>(root.get()); | |
| 55 EXPECT_EQ(2u, list->GetSize()); | |
| 56 int int_val = 0; | |
| 57 EXPECT_TRUE(list->GetInteger(0, &int_val)); | |
| 58 EXPECT_EQ(1, int_val); | |
| 59 EXPECT_TRUE(list->GetInteger(1, &int_val)); | |
| 60 EXPECT_EQ(3, int_val); | |
| 61 root = JSONReader().ReadToValue("[1, /*a*/2, 3]"); | |
| 62 ASSERT_TRUE(root.get()); | |
| 63 list = static_cast<ListValue*>(root.get()); | |
| 64 EXPECT_EQ(3u, list->GetSize()); | |
| 65 root = JSONReader().ReadToValue("/* comment **/42"); | |
| 66 ASSERT_TRUE(root.get()); | |
| 67 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | |
| 68 EXPECT_TRUE(root->GetAsInteger(&int_val)); | |
| 69 EXPECT_EQ(42, int_val); | |
| 70 root = JSONReader().ReadToValue( | |
| 71 "/* comment **/\n" | |
| 72 "// */ 43\n" | |
| 73 "44"); | |
| 74 ASSERT_TRUE(root.get()); | |
| 75 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | |
| 76 EXPECT_TRUE(root->GetAsInteger(&int_val)); | |
| 77 EXPECT_EQ(44, int_val); | |
| 78 | |
| 79 // Test number formats | |
| 80 root = JSONReader().ReadToValue("43"); | |
| 81 ASSERT_TRUE(root.get()); | |
| 82 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | |
| 83 EXPECT_TRUE(root->GetAsInteger(&int_val)); | |
| 84 EXPECT_EQ(43, int_val); | |
| 85 | |
| 86 // According to RFC4627, oct, hex, and leading zeros are invalid JSON. | |
| 87 root = JSONReader().ReadToValue("043"); | |
| 88 EXPECT_FALSE(root.get()); | |
| 89 root = JSONReader().ReadToValue("0x43"); | |
| 90 EXPECT_FALSE(root.get()); | |
| 91 root = JSONReader().ReadToValue("00"); | |
| 92 EXPECT_FALSE(root.get()); | |
| 93 | |
| 94 // Test 0 (which needs to be special cased because of the leading zero | |
| 95 // clause). | |
| 96 root = JSONReader().ReadToValue("0"); | |
| 97 ASSERT_TRUE(root.get()); | |
| 98 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | |
| 99 int_val = 1; | |
| 100 EXPECT_TRUE(root->GetAsInteger(&int_val)); | |
| 101 EXPECT_EQ(0, int_val); | |
| 102 | |
| 103 // Numbers that overflow ints should succeed, being internally promoted to | |
| 104 // storage as doubles | |
| 105 root = JSONReader().ReadToValue("2147483648"); | |
| 106 ASSERT_TRUE(root.get()); | |
| 107 double double_val; | |
| 108 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 109 double_val = 0.0; | |
| 110 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 111 EXPECT_DOUBLE_EQ(2147483648.0, double_val); | |
| 112 root = JSONReader().ReadToValue("-2147483649"); | |
| 113 ASSERT_TRUE(root.get()); | |
| 114 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 115 double_val = 0.0; | |
| 116 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 117 EXPECT_DOUBLE_EQ(-2147483649.0, double_val); | |
| 118 | |
| 119 // Parse a double | |
| 120 root = JSONReader().ReadToValue("43.1"); | |
| 121 ASSERT_TRUE(root.get()); | |
| 122 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 123 double_val = 0.0; | |
| 124 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 125 EXPECT_DOUBLE_EQ(43.1, double_val); | |
| 126 | |
| 127 root = JSONReader().ReadToValue("4.3e-1"); | |
| 128 ASSERT_TRUE(root.get()); | |
| 129 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 130 double_val = 0.0; | |
| 131 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 132 EXPECT_DOUBLE_EQ(.43, double_val); | |
| 133 | |
| 134 root = JSONReader().ReadToValue("2.1e0"); | |
| 135 ASSERT_TRUE(root.get()); | |
| 136 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 137 double_val = 0.0; | |
| 138 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 139 EXPECT_DOUBLE_EQ(2.1, double_val); | |
| 140 | |
| 141 root = JSONReader().ReadToValue("2.1e+0001"); | |
| 142 ASSERT_TRUE(root.get()); | |
| 143 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 144 double_val = 0.0; | |
| 145 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 146 EXPECT_DOUBLE_EQ(21.0, double_val); | |
| 147 | |
| 148 root = JSONReader().ReadToValue("0.01"); | |
| 149 ASSERT_TRUE(root.get()); | |
| 150 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 151 double_val = 0.0; | |
| 152 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 153 EXPECT_DOUBLE_EQ(0.01, double_val); | |
| 154 | |
| 155 root = JSONReader().ReadToValue("1.00"); | |
| 156 ASSERT_TRUE(root.get()); | |
| 157 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | |
| 158 double_val = 0.0; | |
| 159 EXPECT_TRUE(root->GetAsDouble(&double_val)); | |
| 160 EXPECT_DOUBLE_EQ(1.0, double_val); | |
| 161 | |
| 162 // Fractional parts must have a digit before and after the decimal point. | |
| 163 root = JSONReader().ReadToValue("1."); | |
| 164 EXPECT_FALSE(root.get()); | |
| 165 root = JSONReader().ReadToValue(".1"); | |
| 166 EXPECT_FALSE(root.get()); | |
| 167 root = JSONReader().ReadToValue("1.e10"); | |
| 168 EXPECT_FALSE(root.get()); | |
| 169 | |
| 170 // Exponent must have a digit following the 'e'. | |
| 171 root = JSONReader().ReadToValue("1e"); | |
| 172 EXPECT_FALSE(root.get()); | |
| 173 root = JSONReader().ReadToValue("1E"); | |
| 174 EXPECT_FALSE(root.get()); | |
| 175 root = JSONReader().ReadToValue("1e1."); | |
| 176 EXPECT_FALSE(root.get()); | |
| 177 root = JSONReader().ReadToValue("1e1.0"); | |
| 178 EXPECT_FALSE(root.get()); | |
| 179 | |
| 180 // INF/-INF/NaN are not valid | |
| 181 root = JSONReader().ReadToValue("1e1000"); | |
| 182 EXPECT_FALSE(root.get()); | |
| 183 root = JSONReader().ReadToValue("-1e1000"); | |
| 184 EXPECT_FALSE(root.get()); | |
| 185 root = JSONReader().ReadToValue("NaN"); | |
| 186 EXPECT_FALSE(root.get()); | |
| 187 root = JSONReader().ReadToValue("nan"); | |
| 188 EXPECT_FALSE(root.get()); | |
| 189 root = JSONReader().ReadToValue("inf"); | |
| 190 EXPECT_FALSE(root.get()); | |
| 191 | |
| 192 // Invalid number formats | |
| 193 root = JSONReader().ReadToValue("4.3.1"); | |
| 194 EXPECT_FALSE(root.get()); | |
| 195 root = JSONReader().ReadToValue("4e3.1"); | |
| 196 EXPECT_FALSE(root.get()); | |
| 197 | |
| 198 // Test string parser | |
| 199 root = JSONReader().ReadToValue("\"hello world\""); | |
| 200 ASSERT_TRUE(root.get()); | |
| 201 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 202 std::string str_val; | |
| 203 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 204 EXPECT_EQ("hello world", str_val); | |
| 205 | |
| 206 // Empty string | |
| 207 root = JSONReader().ReadToValue("\"\""); | |
| 208 ASSERT_TRUE(root.get()); | |
| 209 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 210 str_val.clear(); | |
| 211 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 212 EXPECT_EQ("", str_val); | |
| 213 | |
| 214 // Test basic string escapes | |
| 215 root = JSONReader().ReadToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\""); | |
| 216 ASSERT_TRUE(root.get()); | |
| 217 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 218 str_val.clear(); | |
| 219 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 220 EXPECT_EQ(" \"\\/\b\f\n\r\t\v", str_val); | |
| 221 | |
| 222 // Test hex and unicode escapes including the null character. | |
| 223 root = JSONReader().ReadToValue("\"\\x41\\x00\\u1234\""); | |
| 224 ASSERT_TRUE(root.get()); | |
| 225 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 226 str_val.clear(); | |
| 227 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 228 EXPECT_EQ(std::wstring(L"A\0\x1234", 3), UTF8ToWide(str_val)); | |
| 229 | |
| 230 // Test invalid strings | |
| 231 root = JSONReader().ReadToValue("\"no closing quote"); | |
| 232 EXPECT_FALSE(root.get()); | |
| 233 root = JSONReader().ReadToValue("\"\\z invalid escape char\""); | |
| 234 EXPECT_FALSE(root.get()); | |
| 235 root = JSONReader().ReadToValue("\"\\xAQ invalid hex code\""); | |
| 236 EXPECT_FALSE(root.get()); | |
| 237 root = JSONReader().ReadToValue("not enough hex chars\\x1\""); | |
| 238 EXPECT_FALSE(root.get()); | |
| 239 root = JSONReader().ReadToValue("\"not enough escape chars\\u123\""); | |
| 240 EXPECT_FALSE(root.get()); | |
| 241 root = JSONReader().ReadToValue("\"extra backslash at end of input\\\""); | |
| 242 EXPECT_FALSE(root.get()); | |
| 243 | |
| 244 // Basic array | |
| 245 root.reset(JSONReader::DeprecatedRead("[true, false, null]")); | |
| 246 ASSERT_TRUE(root.get()); | |
| 247 EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | |
| 248 list = static_cast<ListValue*>(root.get()); | |
| 249 EXPECT_EQ(3U, list->GetSize()); | |
| 250 | |
| 251 // Test with trailing comma. Should be parsed the same as above. | |
| 252 scoped_ptr<Value> root2; | |
| 253 root2.reset(JSONReader::DeprecatedRead("[true, false, null, ]", | |
| 254 JSON_ALLOW_TRAILING_COMMAS)); | |
| 255 EXPECT_TRUE(root->Equals(root2.get())); | |
| 256 | |
| 257 // Empty array | |
| 258 root.reset(JSONReader::DeprecatedRead("[]")); | |
| 259 ASSERT_TRUE(root.get()); | |
| 260 EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | |
| 261 list = static_cast<ListValue*>(root.get()); | |
| 262 EXPECT_EQ(0U, list->GetSize()); | |
| 263 | |
| 264 // Nested arrays | |
| 265 root.reset( | |
| 266 JSONReader::DeprecatedRead("[[true], [], [false, [], [null]], null]")); | |
| 267 ASSERT_TRUE(root.get()); | |
| 268 EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | |
| 269 list = static_cast<ListValue*>(root.get()); | |
| 270 EXPECT_EQ(4U, list->GetSize()); | |
| 271 | |
| 272 // Lots of trailing commas. | |
| 273 root2.reset(JSONReader::DeprecatedRead( | |
| 274 "[[true], [], [false, [], [null, ] , ], null,]", | |
| 275 JSON_ALLOW_TRAILING_COMMAS)); | |
| 276 EXPECT_TRUE(root->Equals(root2.get())); | |
| 277 | |
| 278 // Invalid, missing close brace. | |
| 279 root.reset( | |
| 280 JSONReader::DeprecatedRead("[[true], [], [false, [], [null]], null")); | |
| 281 EXPECT_FALSE(root.get()); | |
| 282 | |
| 283 // Invalid, too many commas | |
| 284 root.reset(JSONReader::DeprecatedRead("[true,, null]")); | |
| 285 EXPECT_FALSE(root.get()); | |
| 286 root.reset( | |
| 287 JSONReader::DeprecatedRead("[true,, null]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 288 EXPECT_FALSE(root.get()); | |
| 289 | |
| 290 // Invalid, no commas | |
| 291 root.reset(JSONReader::DeprecatedRead("[true null]")); | |
| 292 EXPECT_FALSE(root.get()); | |
| 293 | |
| 294 // Invalid, trailing comma | |
| 295 root.reset(JSONReader::DeprecatedRead("[true,]")); | |
| 296 EXPECT_FALSE(root.get()); | |
| 297 | |
| 298 // Valid if we set |allow_trailing_comma| to true. | |
| 299 root.reset(JSONReader::DeprecatedRead("[true,]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 300 ASSERT_TRUE(root.get()); | |
| 301 EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | |
| 302 list = static_cast<ListValue*>(root.get()); | |
| 303 EXPECT_EQ(1U, list->GetSize()); | |
| 304 Value* tmp_value = NULL; | |
| 305 ASSERT_TRUE(list->Get(0, &tmp_value)); | |
| 306 EXPECT_TRUE(tmp_value->IsType(Value::TYPE_BOOLEAN)); | |
| 307 bool bool_value = false; | |
| 308 EXPECT_TRUE(tmp_value->GetAsBoolean(&bool_value)); | |
| 309 EXPECT_TRUE(bool_value); | |
| 310 | |
| 311 // Don't allow empty elements, even if |allow_trailing_comma| is | |
| 312 // true. | |
| 313 root.reset(JSONReader::DeprecatedRead("[,]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 314 EXPECT_FALSE(root.get()); | |
| 315 root.reset( | |
| 316 JSONReader::DeprecatedRead("[true,,]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 317 EXPECT_FALSE(root.get()); | |
| 318 root.reset( | |
| 319 JSONReader::DeprecatedRead("[,true,]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 320 EXPECT_FALSE(root.get()); | |
| 321 root.reset( | |
| 322 JSONReader::DeprecatedRead("[true,,false]", JSON_ALLOW_TRAILING_COMMAS)); | |
| 323 EXPECT_FALSE(root.get()); | |
| 324 | |
| 325 // Test objects | |
| 326 root.reset(JSONReader::DeprecatedRead("{}")); | |
| 327 ASSERT_TRUE(root.get()); | |
| 328 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 329 | |
| 330 root.reset(JSONReader::DeprecatedRead( | |
| 331 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\" }")); | |
| 332 ASSERT_TRUE(root.get()); | |
| 333 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 334 DictionaryValue* dict_val = static_cast<DictionaryValue*>(root.get()); | |
| 335 double_val = 0.0; | |
| 336 EXPECT_TRUE(dict_val->GetDouble("number", &double_val)); | |
| 337 EXPECT_DOUBLE_EQ(9.87654321, double_val); | |
| 338 Value* null_val = NULL; | |
| 339 ASSERT_TRUE(dict_val->Get("null", &null_val)); | |
| 340 EXPECT_TRUE(null_val->IsType(Value::TYPE_NULL)); | |
| 341 str_val.clear(); | |
| 342 EXPECT_TRUE(dict_val->GetString("S", &str_val)); | |
| 343 EXPECT_EQ("str", str_val); | |
| 344 | |
| 345 root2.reset(JSONReader::DeprecatedRead( | |
| 346 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", }", | |
| 347 JSON_ALLOW_TRAILING_COMMAS)); | |
| 348 ASSERT_TRUE(root2.get()); | |
| 349 EXPECT_TRUE(root->Equals(root2.get())); | |
| 350 | |
| 351 // Test newline equivalence. | |
| 352 root2.reset(JSONReader::DeprecatedRead( | |
| 353 "{\n" | |
| 354 " \"number\":9.87654321,\n" | |
| 355 " \"null\":null,\n" | |
| 356 " \"\\x53\":\"str\",\n" | |
| 357 "}\n", | |
| 358 JSON_ALLOW_TRAILING_COMMAS)); | |
| 359 ASSERT_TRUE(root2.get()); | |
| 360 EXPECT_TRUE(root->Equals(root2.get())); | |
| 361 | |
| 362 root2.reset(JSONReader::DeprecatedRead( | |
| 363 "{\r\n" | |
| 364 " \"number\":9.87654321,\r\n" | |
| 365 " \"null\":null,\r\n" | |
| 366 " \"\\x53\":\"str\",\r\n" | |
| 367 "}\r\n", | |
| 368 JSON_ALLOW_TRAILING_COMMAS)); | |
| 369 ASSERT_TRUE(root2.get()); | |
| 370 EXPECT_TRUE(root->Equals(root2.get())); | |
| 371 | |
| 372 // Test nesting | |
| 373 root.reset(JSONReader::DeprecatedRead( | |
| 374 "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}")); | |
| 375 ASSERT_TRUE(root.get()); | |
| 376 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 377 dict_val = static_cast<DictionaryValue*>(root.get()); | |
| 378 DictionaryValue* inner_dict = NULL; | |
| 379 ASSERT_TRUE(dict_val->GetDictionary("inner", &inner_dict)); | |
| 380 ListValue* inner_array = NULL; | |
| 381 ASSERT_TRUE(inner_dict->GetList("array", &inner_array)); | |
| 382 EXPECT_EQ(1U, inner_array->GetSize()); | |
| 383 bool_value = true; | |
| 384 EXPECT_TRUE(dict_val->GetBoolean("false", &bool_value)); | |
| 385 EXPECT_FALSE(bool_value); | |
| 386 inner_dict = NULL; | |
| 387 EXPECT_TRUE(dict_val->GetDictionary("d", &inner_dict)); | |
| 388 | |
| 389 root2.reset(JSONReader::DeprecatedRead( | |
| 390 "{\"inner\": {\"array\":[true] , },\"false\":false,\"d\":{},}", | |
| 391 JSON_ALLOW_TRAILING_COMMAS)); | |
| 392 EXPECT_TRUE(root->Equals(root2.get())); | |
| 393 | |
| 394 // Test keys with periods | |
| 395 root.reset(JSONReader::DeprecatedRead( | |
| 396 "{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}")); | |
| 397 ASSERT_TRUE(root.get()); | |
| 398 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 399 dict_val = static_cast<DictionaryValue*>(root.get()); | |
| 400 int integer_value = 0; | |
| 401 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("a.b", &integer_value)); | |
| 402 EXPECT_EQ(3, integer_value); | |
| 403 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("c", &integer_value)); | |
| 404 EXPECT_EQ(2, integer_value); | |
| 405 inner_dict = NULL; | |
| 406 ASSERT_TRUE(dict_val->GetDictionaryWithoutPathExpansion("d.e.f", | |
| 407 &inner_dict)); | |
| 408 EXPECT_EQ(1U, inner_dict->size()); | |
| 409 EXPECT_TRUE(inner_dict->GetIntegerWithoutPathExpansion("g.h.i.j", | |
| 410 &integer_value)); | |
| 411 EXPECT_EQ(1, integer_value); | |
| 412 | |
| 413 root.reset(JSONReader::DeprecatedRead("{\"a\":{\"b\":2},\"a.b\":1}")); | |
| 414 ASSERT_TRUE(root.get()); | |
| 415 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 416 dict_val = static_cast<DictionaryValue*>(root.get()); | |
| 417 EXPECT_TRUE(dict_val->GetInteger("a.b", &integer_value)); | |
| 418 EXPECT_EQ(2, integer_value); | |
| 419 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("a.b", &integer_value)); | |
| 420 EXPECT_EQ(1, integer_value); | |
| 421 | |
| 422 // Invalid, no closing brace | |
| 423 root.reset(JSONReader::DeprecatedRead("{\"a\": true")); | |
| 424 EXPECT_FALSE(root.get()); | |
| 425 | |
| 426 // Invalid, keys must be quoted | |
| 427 root.reset(JSONReader::DeprecatedRead("{foo:true}")); | |
| 428 EXPECT_FALSE(root.get()); | |
| 429 | |
| 430 // Invalid, trailing comma | |
| 431 root.reset(JSONReader::DeprecatedRead("{\"a\":true,}")); | |
| 432 EXPECT_FALSE(root.get()); | |
| 433 | |
| 434 // Invalid, too many commas | |
| 435 root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}")); | |
| 436 EXPECT_FALSE(root.get()); | |
| 437 root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}", | |
| 438 JSON_ALLOW_TRAILING_COMMAS)); | |
| 439 EXPECT_FALSE(root.get()); | |
| 440 | |
| 441 // Invalid, no separator | |
| 442 root.reset(JSONReader::DeprecatedRead("{\"a\" \"b\"}")); | |
| 443 EXPECT_FALSE(root.get()); | |
| 444 | |
| 445 // Invalid, lone comma. | |
| 446 root.reset(JSONReader::DeprecatedRead("{,}")); | |
| 447 EXPECT_FALSE(root.get()); | |
| 448 root.reset(JSONReader::DeprecatedRead("{,}", JSON_ALLOW_TRAILING_COMMAS)); | |
| 449 EXPECT_FALSE(root.get()); | |
| 450 root.reset( | |
| 451 JSONReader::DeprecatedRead("{\"a\":true,,}", JSON_ALLOW_TRAILING_COMMAS)); | |
| 452 EXPECT_FALSE(root.get()); | |
| 453 root.reset( | |
| 454 JSONReader::DeprecatedRead("{,\"a\":true}", JSON_ALLOW_TRAILING_COMMAS)); | |
| 455 EXPECT_FALSE(root.get()); | |
| 456 root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}", | |
| 457 JSON_ALLOW_TRAILING_COMMAS)); | |
| 458 EXPECT_FALSE(root.get()); | |
| 459 | |
| 460 // Test stack overflow | |
| 461 std::string evil(1000000, '['); | |
| 462 evil.append(std::string(1000000, ']')); | |
| 463 root.reset(JSONReader::DeprecatedRead(evil)); | |
| 464 EXPECT_FALSE(root.get()); | |
| 465 | |
| 466 // A few thousand adjacent lists is fine. | |
| 467 std::string not_evil("["); | |
| 468 not_evil.reserve(15010); | |
| 469 for (int i = 0; i < 5000; ++i) { | |
| 470 not_evil.append("[],"); | |
| 471 } | |
| 472 not_evil.append("[]]"); | |
| 473 root.reset(JSONReader::DeprecatedRead(not_evil)); | |
| 474 ASSERT_TRUE(root.get()); | |
| 475 EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | |
| 476 list = static_cast<ListValue*>(root.get()); | |
| 477 EXPECT_EQ(5001U, list->GetSize()); | |
| 478 | |
| 479 // Test utf8 encoded input | |
| 480 root = JSONReader().ReadToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\""); | |
| 481 ASSERT_TRUE(root.get()); | |
| 482 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 483 str_val.clear(); | |
| 484 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 485 EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val)); | |
| 486 | |
| 487 root = JSONReader().ReadToValue( | |
| 488 "{\"path\": \"/tmp/\xc3\xa0\xc3\xa8\xc3\xb2.png\"}"); | |
| 489 ASSERT_TRUE(root.get()); | |
| 490 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 491 EXPECT_TRUE(root->GetAsDictionary(&dict_val)); | |
| 492 EXPECT_TRUE(dict_val->GetString("path", &str_val)); | |
| 493 EXPECT_EQ("/tmp/\xC3\xA0\xC3\xA8\xC3\xB2.png", str_val); | |
| 494 | |
| 495 // Test invalid utf8 encoded input | |
| 496 root = JSONReader().ReadToValue("\"345\xb0\xa1\xb0\xa2\""); | |
| 497 EXPECT_FALSE(root.get()); | |
| 498 root = JSONReader().ReadToValue("\"123\xc0\x81\""); | |
| 499 EXPECT_FALSE(root.get()); | |
| 500 root = JSONReader().ReadToValue("\"abc\xc0\xae\""); | |
| 501 EXPECT_FALSE(root.get()); | |
| 502 | |
| 503 // Test utf16 encoded strings. | |
| 504 root = JSONReader().ReadToValue("\"\\u20ac3,14\""); | |
| 505 ASSERT_TRUE(root.get()); | |
| 506 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 507 str_val.clear(); | |
| 508 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 509 EXPECT_EQ("\xe2\x82\xac""3,14", str_val); | |
| 510 | |
| 511 root = JSONReader().ReadToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\""); | |
| 512 ASSERT_TRUE(root.get()); | |
| 513 EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | |
| 514 str_val.clear(); | |
| 515 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 516 EXPECT_EQ("\xf0\x9f\x92\xa9\xf0\x9f\x91\xac", str_val); | |
| 517 | |
| 518 // Test invalid utf16 strings. | |
| 519 const char* const cases[] = { | |
| 520 "\"\\u123\"", // Invalid scalar. | |
| 521 "\"\\ud83d\"", // Invalid scalar. | |
| 522 "\"\\u$%@!\"", // Invalid scalar. | |
| 523 "\"\\uzz89\"", // Invalid scalar. | |
| 524 "\"\\ud83d\\udca\"", // Invalid lower surrogate. | |
| 525 "\"\\ud83d\\ud83d\"", // Invalid lower surrogate. | |
| 526 "\"\\ud83foo\"", // No lower surrogate. | |
| 527 "\"\\ud83\\foo\"" // No lower surrogate. | |
| 528 }; | |
| 529 for (size_t i = 0; i < arraysize(cases); ++i) { | |
| 530 root = JSONReader().ReadToValue(cases[i]); | |
| 531 EXPECT_FALSE(root.get()) << cases[i]; | |
| 532 } | |
| 533 | |
| 534 // Test literal root objects. | |
| 535 root.reset(JSONReader::DeprecatedRead("null")); | |
| 536 EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | |
| 537 | |
| 538 root.reset(JSONReader::DeprecatedRead("true")); | |
| 539 ASSERT_TRUE(root.get()); | |
| 540 EXPECT_TRUE(root->GetAsBoolean(&bool_value)); | |
| 541 EXPECT_TRUE(bool_value); | |
| 542 | |
| 543 root.reset(JSONReader::DeprecatedRead("10")); | |
| 544 ASSERT_TRUE(root.get()); | |
| 545 EXPECT_TRUE(root->GetAsInteger(&integer_value)); | |
| 546 EXPECT_EQ(10, integer_value); | |
| 547 | |
| 548 root.reset(JSONReader::DeprecatedRead("\"root\"")); | |
| 549 ASSERT_TRUE(root.get()); | |
| 550 EXPECT_TRUE(root->GetAsString(&str_val)); | |
| 551 EXPECT_EQ("root", str_val); | |
| 552 } | |
| 553 | |
| 554 TEST(JSONReaderTest, ReadFromFile) { | |
| 555 FilePath path; | |
| 556 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &path)); | |
| 557 path = path.AppendASCII("json"); | |
| 558 ASSERT_TRUE(base::PathExists(path)); | |
| 559 | |
| 560 std::string input; | |
| 561 ASSERT_TRUE(ReadFileToString( | |
| 562 path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input)); | |
| 563 | |
| 564 JSONReader reader; | |
| 565 scoped_ptr<Value> root(reader.ReadToValue(input)); | |
| 566 ASSERT_TRUE(root.get()) << reader.GetErrorMessage(); | |
| 567 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | |
| 568 } | |
| 569 | |
| 570 // Tests that the root of a JSON object can be deleted safely while its | |
| 571 // children outlive it. | |
| 572 TEST(JSONReaderTest, StringOptimizations) { | |
| 573 scoped_ptr<Value> dict_literal_0; | |
| 574 scoped_ptr<Value> dict_literal_1; | |
| 575 scoped_ptr<Value> dict_string_0; | |
| 576 scoped_ptr<Value> dict_string_1; | |
| 577 scoped_ptr<Value> list_value_0; | |
| 578 scoped_ptr<Value> list_value_1; | |
| 579 | |
| 580 { | |
| 581 scoped_ptr<Value> root = JSONReader::Read( | |
| 582 "{" | |
| 583 " \"test\": {" | |
| 584 " \"foo\": true," | |
| 585 " \"bar\": 3.14," | |
| 586 " \"baz\": \"bat\"," | |
| 587 " \"moo\": \"cow\"" | |
| 588 " }," | |
| 589 " \"list\": [" | |
| 590 " \"a\"," | |
| 591 " \"b\"" | |
| 592 " ]" | |
| 593 "}", | |
| 594 JSON_DETACHABLE_CHILDREN); | |
| 595 ASSERT_TRUE(root.get()); | |
| 596 | |
| 597 DictionaryValue* root_dict = NULL; | |
| 598 ASSERT_TRUE(root->GetAsDictionary(&root_dict)); | |
| 599 | |
| 600 DictionaryValue* dict = NULL; | |
| 601 ListValue* list = NULL; | |
| 602 | |
| 603 ASSERT_TRUE(root_dict->GetDictionary("test", &dict)); | |
| 604 ASSERT_TRUE(root_dict->GetList("list", &list)); | |
| 605 | |
| 606 EXPECT_TRUE(dict->Remove("foo", &dict_literal_0)); | |
| 607 EXPECT_TRUE(dict->Remove("bar", &dict_literal_1)); | |
| 608 EXPECT_TRUE(dict->Remove("baz", &dict_string_0)); | |
| 609 EXPECT_TRUE(dict->Remove("moo", &dict_string_1)); | |
| 610 | |
| 611 ASSERT_EQ(2u, list->GetSize()); | |
| 612 EXPECT_TRUE(list->Remove(0, &list_value_0)); | |
| 613 EXPECT_TRUE(list->Remove(0, &list_value_1)); | |
| 614 } | |
| 615 | |
| 616 bool b = false; | |
| 617 double d = 0; | |
| 618 std::string s; | |
| 619 | |
| 620 EXPECT_TRUE(dict_literal_0->GetAsBoolean(&b)); | |
| 621 EXPECT_TRUE(b); | |
| 622 | |
| 623 EXPECT_TRUE(dict_literal_1->GetAsDouble(&d)); | |
| 624 EXPECT_EQ(3.14, d); | |
| 625 | |
| 626 EXPECT_TRUE(dict_string_0->GetAsString(&s)); | |
| 627 EXPECT_EQ("bat", s); | |
| 628 | |
| 629 EXPECT_TRUE(dict_string_1->GetAsString(&s)); | |
| 630 EXPECT_EQ("cow", s); | |
| 631 | |
| 632 EXPECT_TRUE(list_value_0->GetAsString(&s)); | |
| 633 EXPECT_EQ("a", s); | |
| 634 EXPECT_TRUE(list_value_1->GetAsString(&s)); | |
| 635 EXPECT_EQ("b", s); | |
| 636 } | |
| 637 | |
| 638 // A smattering of invalid JSON designed to test specific portions of the | |
| 639 // parser implementation against buffer overflow. Best run with DCHECKs so | |
| 640 // that the one in NextChar fires. | |
| 641 TEST(JSONReaderTest, InvalidSanity) { | |
| 642 const char* const invalid_json[] = { | |
| 643 "/* test *", | |
| 644 "{\"foo\"", | |
| 645 "{\"foo\":", | |
| 646 " [", | |
| 647 "\"\\u123g\"", | |
| 648 "{\n\"eh:\n}", | |
| 649 }; | |
| 650 | |
| 651 for (size_t i = 0; i < arraysize(invalid_json); ++i) { | |
| 652 JSONReader reader; | |
| 653 LOG(INFO) << "Sanity test " << i << ": <" << invalid_json[i] << ">"; | |
| 654 EXPECT_FALSE(reader.ReadToValue(invalid_json[i])); | |
| 655 EXPECT_NE(JSONReader::JSON_NO_ERROR, reader.error_code()); | |
| 656 EXPECT_NE("", reader.GetErrorMessage()); | |
| 657 } | |
| 658 } | |
| 659 | |
| 660 TEST(JSONReaderTest, IllegalTrailingNull) { | |
| 661 const char json[] = { '"', 'n', 'u', 'l', 'l', '"', '\0' }; | |
| 662 std::string json_string(json, sizeof(json)); | |
| 663 JSONReader reader; | |
| 664 EXPECT_FALSE(reader.ReadToValue(json_string)); | |
| 665 EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, reader.error_code()); | |
| 666 } | |
| 667 | |
| 668 } // namespace base | |
| OLD | NEW |