1 // Copyright 2012 The Chromium Authors
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 <stddef.h>
8
9 #include <cmath>
10 #include <string_view>
11 #include <utility>
12
13 #include "base/base_paths.h"
14 #include "base/features.h"
15 #include "base/files/file_util.h"
16 #include "base/logging.h"
17 #include "base/path_service.h"
18 #include "base/rust_buildflags.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/gmock_expected_support.h"
22 #include "base/test/metrics/histogram_tester.h"
23 #include "base/test/scoped_feature_list.h"
24 #include "base/values.h"
25 #include "build/build_config.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace {
30
31 // MSan will do a better job detecting over-read errors if the input is not
32 // nul-terminated on the heap. This will copy |input| to a new buffer owned by
33 // |owner|, returning a std::string_view to |owner|.
MakeNotNullTerminatedInput(const char * input,std::unique_ptr<char[]> * owner)34 std::string_view MakeNotNullTerminatedInput(const char* input,
35 std::unique_ptr<char[]>* owner) {
36 size_t str_len = strlen(input);
37 owner->reset(new char[str_len]);
38 memcpy(owner->get(), input, str_len);
39 return std::string_view(owner->get(), str_len);
40 }
41
42 } // namespace
43
44 namespace base {
45
46 class JSONReaderTest : public testing::TestWithParam<bool> {
47 public:
SetUp()48 void SetUp() override {
49 feature_list_.InitWithFeatureState(base::features::kUseRustJsonParser,
50 using_rust_);
51 }
52
53 protected:
54 bool using_rust_ = GetParam();
55 base::test::ScopedFeatureList feature_list_;
56 };
57
TEST_P(JSONReaderTest,Whitespace)58 TEST_P(JSONReaderTest, Whitespace) {
59 std::optional<Value> root = JSONReader::Read(" null ");
60 ASSERT_TRUE(root);
61 EXPECT_TRUE(root->is_none());
62 }
63
TEST_P(JSONReaderTest,InvalidString)64 TEST_P(JSONReaderTest, InvalidString) {
65 // These are invalid because they do not represent a JSON value,
66 // see https://tools.ietf.org/rfc/rfc8259.txt
67 EXPECT_FALSE(JSONReader::Read(""));
68 EXPECT_FALSE(JSONReader::Read("nu"));
69 }
70
TEST_P(JSONReaderTest,SimpleBool)71 TEST_P(JSONReaderTest, SimpleBool) {
72 #if BUILDFLAG(BUILD_RUST_JSON_READER)
73 base::HistogramTester histograms;
74 #endif // BUILDFLAG(BUILD_RUST_JSON_READER)
75 std::optional<Value> root = JSONReader::Read("true ");
76 ASSERT_TRUE(root);
77 EXPECT_TRUE(root->is_bool());
78 #if BUILDFLAG(BUILD_RUST_JSON_READER)
79 histograms.ExpectTotalCount("Security.JSONParser.ParsingTime", 1);
80 #endif // BUILDFLAG(BUILD_RUST_JSON_READER)
81 }
82
TEST_P(JSONReaderTest,EmbeddedComments)83 TEST_P(JSONReaderTest, EmbeddedComments) {
84 std::optional<Value> root = JSONReader::Read("/* comment */null");
85 ASSERT_TRUE(root);
86 EXPECT_TRUE(root->is_none());
87 root = JSONReader::Read("40 /* comment */");
88 ASSERT_TRUE(root);
89 EXPECT_TRUE(root->is_int());
90 root = JSONReader::Read("true // comment");
91 ASSERT_TRUE(root);
92 EXPECT_TRUE(root->is_bool());
93 // Comments in different contexts.
94 root = JSONReader::Read("{ \"cheese\": 3\n\n // Here's a comment\n}");
95 ASSERT_TRUE(root);
96 EXPECT_TRUE(root->is_dict());
97 root = JSONReader::Read("{ \"cheese\": 3// Here's a comment\n}");
98 ASSERT_TRUE(root);
99 EXPECT_TRUE(root->is_dict());
100 // Multiple comment markers.
101 root = JSONReader::Read(
102 "{ \"cheese\": 3// Here's a comment // and another\n}");
103 ASSERT_TRUE(root);
104 EXPECT_TRUE(root->is_dict());
105 root = JSONReader::Read("/* comment */\"sample string\"");
106 ASSERT_TRUE(root);
107 ASSERT_TRUE(root->is_string());
108 EXPECT_EQ("sample string", root->GetString());
109 root = JSONReader::Read("[1, /* comment, 2 ] */ \n 3]");
110 ASSERT_TRUE(root);
111 Value::List* list = root->GetIfList();
112 ASSERT_TRUE(list);
113 ASSERT_EQ(2u, list->size());
114 ASSERT_TRUE((*list)[0].is_int());
115 EXPECT_EQ(1, (*list)[0].GetInt());
116 ASSERT_TRUE((*list)[1].is_int());
117 EXPECT_EQ(3, (*list)[1].GetInt());
118 root = JSONReader::Read("[1, /*a*/2, 3]");
119 ASSERT_TRUE(root);
120 list = root->GetIfList();
121 ASSERT_TRUE(list);
122 EXPECT_EQ(3u, (*list).size());
123 root = JSONReader::Read("/* comment **/42");
124 ASSERT_TRUE(root);
125 ASSERT_TRUE(root->is_int());
126 EXPECT_EQ(42, root->GetInt());
127 root = JSONReader::Read(
128 "/* comment **/\n"
129 "// */ 43\n"
130 "44");
131 ASSERT_TRUE(root);
132 EXPECT_TRUE(root->is_int());
133 EXPECT_EQ(44, root->GetInt());
134
135 // At one point, this parsed successfully as the value three.
136 EXPECT_FALSE(JSONReader::Read("/33"));
137 }
138
TEST_P(JSONReaderTest,Ints)139 TEST_P(JSONReaderTest, Ints) {
140 std::optional<Value> root = JSONReader::Read("43");
141 ASSERT_TRUE(root);
142 ASSERT_TRUE(root->is_int());
143 EXPECT_EQ(43, root->GetInt());
144 }
145
TEST_P(JSONReaderTest,NonDecimalNumbers)146 TEST_P(JSONReaderTest, NonDecimalNumbers) {
147 // According to RFC 8259, oct, hex, and leading zeros are invalid JSON.
148 EXPECT_FALSE(JSONReader::Read("043"));
149 EXPECT_FALSE(JSONReader::Read("0x43"));
150 EXPECT_FALSE(JSONReader::Read("00"));
151 }
152
TEST_P(JSONReaderTest,NumberZero)153 TEST_P(JSONReaderTest, NumberZero) {
154 // Test 0 (which needs to be special cased because of the leading zero
155 // clause).
156 std::optional<Value> root = JSONReader::Read("0");
157 ASSERT_TRUE(root);
158 ASSERT_TRUE(root->is_int());
159 EXPECT_EQ(0, root->GetInt());
160 }
161
TEST_P(JSONReaderTest,LargeIntPromotion)162 TEST_P(JSONReaderTest, LargeIntPromotion) {
163 // Numbers that overflow ints should succeed, being internally promoted to
164 // storage as doubles
165 std::optional<Value> root = JSONReader::Read("2147483648");
166 ASSERT_TRUE(root);
167 EXPECT_TRUE(root->is_double());
168 EXPECT_DOUBLE_EQ(2147483648.0, root->GetDouble());
169 root = JSONReader::Read("-2147483649");
170 ASSERT_TRUE(root);
171 EXPECT_TRUE(root->is_double());
172 EXPECT_DOUBLE_EQ(-2147483649.0, root->GetDouble());
173 }
174
TEST_P(JSONReaderTest,LargerIntIsLossy)175 TEST_P(JSONReaderTest, LargerIntIsLossy) {
176 // Parse LONG_MAX as a JSON number (not a JSON string). The result of the
177 // parse is a base::Value, either a (32-bit) int or a (64-bit) double.
178 // LONG_MAX would overflow an int and can only be approximated by a double.
179 // In this case, parsing is lossy.
180 const char* etc807 = "9223372036854775807";
181 const char* etc808 = "9223372036854775808.000000";
182 std::optional<Value> root = JSONReader::Read(etc807);
183 ASSERT_TRUE(root);
184 ASSERT_FALSE(root->is_int());
185 ASSERT_TRUE(root->is_double());
186 // We use StringPrintf instead of NumberToString, because the NumberToString
187 // function does not let you specify the precision, and its default output,
188 // "9.223372036854776e+18", isn't precise enough to see the lossiness.
189 EXPECT_EQ(std::string(etc808), StringPrintf("%f", root->GetDouble()));
190 }
191
TEST_P(JSONReaderTest,Doubles)192 TEST_P(JSONReaderTest, Doubles) {
193 std::optional<Value> root = JSONReader::Read("43.1");
194 ASSERT_TRUE(root);
195 EXPECT_TRUE(root->is_double());
196 EXPECT_DOUBLE_EQ(43.1, root->GetDouble());
197
198 root = JSONReader::Read("4.3e-1");
199 ASSERT_TRUE(root);
200 EXPECT_TRUE(root->is_double());
201 EXPECT_DOUBLE_EQ(.43, root->GetDouble());
202
203 root = JSONReader::Read("2.1e0");
204 ASSERT_TRUE(root);
205 EXPECT_TRUE(root->is_double());
206 EXPECT_DOUBLE_EQ(2.1, root->GetDouble());
207
208 root = JSONReader::Read("2.1e+0001");
209 ASSERT_TRUE(root);
210 EXPECT_TRUE(root->is_double());
211 EXPECT_DOUBLE_EQ(21.0, root->GetDouble());
212
213 root = JSONReader::Read("0.01");
214 ASSERT_TRUE(root);
215 EXPECT_TRUE(root->is_double());
216 EXPECT_DOUBLE_EQ(0.01, root->GetDouble());
217
218 root = JSONReader::Read("1.00");
219 ASSERT_TRUE(root);
220 EXPECT_TRUE(root->is_double());
221 EXPECT_DOUBLE_EQ(1.0, root->GetDouble());
222
223 // Some "parse to float64" implementations find this one tricky.
224 // https://github.com/serde-rs/json/issues/707
225 root = JSONReader::Read("122.416294033786585");
226 ASSERT_TRUE(root);
227 EXPECT_TRUE(root->is_double());
228 EXPECT_DOUBLE_EQ(122.416294033786585, root->GetDouble());
229
230 // This is syntaxtically valid, but out of range of a double.
231 auto value =
232 JSONReader::ReadAndReturnValueWithError("1e1000", JSON_PARSE_RFC);
233 ASSERT_FALSE(value.has_value());
234 }
235
TEST_P(JSONReaderTest,FractionalNumbers)236 TEST_P(JSONReaderTest, FractionalNumbers) {
237 // Fractional parts must have a digit before and after the decimal point.
238 EXPECT_FALSE(JSONReader::Read("1."));
239 EXPECT_FALSE(JSONReader::Read(".1"));
240 EXPECT_FALSE(JSONReader::Read("1.e10"));
241 }
242
TEST_P(JSONReaderTest,ExponentialNumbers)243 TEST_P(JSONReaderTest, ExponentialNumbers) {
244 // Exponent must have a digit following the 'e'.
245 EXPECT_FALSE(JSONReader::Read("1e"));
246 EXPECT_FALSE(JSONReader::Read("1E"));
247 EXPECT_FALSE(JSONReader::Read("1e1."));
248 EXPECT_FALSE(JSONReader::Read("1e1.0"));
249 }
250
TEST_P(JSONReaderTest,InvalidInfNAN)251 TEST_P(JSONReaderTest, InvalidInfNAN) {
252 // The largest finite double is roughly 1.8e308.
253 EXPECT_FALSE(JSONReader::Read("1e1000"));
254 EXPECT_FALSE(JSONReader::Read("-1e1000"));
255 EXPECT_FALSE(JSONReader::Read("NaN"));
256 EXPECT_FALSE(JSONReader::Read("nan"));
257 EXPECT_FALSE(JSONReader::Read("inf"));
258 }
259
TEST_P(JSONReaderTest,InvalidNumbers)260 TEST_P(JSONReaderTest, InvalidNumbers) {
261 EXPECT_TRUE(JSONReader::Read("4.3"));
262 EXPECT_FALSE(JSONReader::Read("4."));
263 EXPECT_FALSE(JSONReader::Read("4.3.1"));
264 EXPECT_FALSE(JSONReader::Read("4e3.1"));
265 EXPECT_FALSE(JSONReader::Read("4.a"));
266 EXPECT_FALSE(JSONReader::Read("42a"));
267 }
268
TEST_P(JSONReaderTest,Zeroes)269 TEST_P(JSONReaderTest, Zeroes) {
270 std::optional<Value> root = JSONReader::Read("0");
271 ASSERT_TRUE(root);
272 EXPECT_TRUE(root->is_int());
273 EXPECT_DOUBLE_EQ(0, root->GetInt());
274
275 root = JSONReader::Read("0.0");
276 ASSERT_TRUE(root);
277 EXPECT_TRUE(root->is_double());
278 EXPECT_DOUBLE_EQ(0.0, root->GetDouble());
279 EXPECT_FALSE(std::signbit(root->GetDouble()));
280
281 root = JSONReader::Read("-0");
282 ASSERT_TRUE(root);
283 EXPECT_TRUE(root->is_double());
284 EXPECT_DOUBLE_EQ(0.0, root->GetDouble());
285 EXPECT_TRUE(std::signbit(root->GetDouble()));
286
287 root = JSONReader::Read("-0.0");
288 ASSERT_TRUE(root);
289 EXPECT_TRUE(root->is_double());
290 EXPECT_DOUBLE_EQ(-0.0, root->GetDouble());
291 EXPECT_TRUE(std::signbit(root->GetDouble()));
292 }
293
TEST_P(JSONReaderTest,SimpleString)294 TEST_P(JSONReaderTest, SimpleString) {
295 std::optional<Value> root = JSONReader::Read("\"hello world\"");
296 ASSERT_TRUE(root);
297 ASSERT_TRUE(root->is_string());
298 EXPECT_EQ("hello world", root->GetString());
299 }
300
TEST_P(JSONReaderTest,EmptyString)301 TEST_P(JSONReaderTest, EmptyString) {
302 std::optional<Value> root = JSONReader::Read("\"\"");
303 ASSERT_TRUE(root);
304 ASSERT_TRUE(root->is_string());
305 EXPECT_EQ("", root->GetString());
306 }
307
TEST_P(JSONReaderTest,BasicStringEscapes)308 TEST_P(JSONReaderTest, BasicStringEscapes) {
309 std::optional<Value> root =
310 JSONReader::Read("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\"");
311 ASSERT_TRUE(root);
312 ASSERT_TRUE(root->is_string());
313 EXPECT_EQ(" \"\\/\b\f\n\r\t", root->GetString());
314 }
315
TEST_P(JSONReaderTest,UnicodeEscapes)316 TEST_P(JSONReaderTest, UnicodeEscapes) {
317 // Test hex and unicode escapes including the null character.
318 std::optional<Value> root =
319 JSONReader::Read("\"\\x41\\xFF\\x00\\u1234\\u0000\"");
320 ASSERT_TRUE(root);
321 ASSERT_TRUE(root->is_string());
322 const std::string& str_val = root->GetString();
323 EXPECT_EQ(std::wstring(L"A\x00FF\0\x1234\0", 5), UTF8ToWide(str_val));
324
325 // The contents of a Unicode escape may only be four hex chars. Previously the
326 // parser accepted things like "0x01" and "0X01".
327 EXPECT_FALSE(JSONReader::Read("\"\\u0x12\""));
328
329 // Surrogate pairs are allowed in JSON.
330 EXPECT_TRUE(JSONReader::Read("\"\\uD834\\uDD1E\"")); // U+1D11E
331 }
332
TEST_P(JSONReaderTest,InvalidStrings)333 TEST_P(JSONReaderTest, InvalidStrings) {
334 EXPECT_FALSE(JSONReader::Read("\"no closing quote"));
335 EXPECT_FALSE(JSONReader::Read("\"\\z invalid escape char\""));
336 EXPECT_FALSE(JSONReader::Read("\"\\xAQ invalid hex code\""));
337 EXPECT_FALSE(JSONReader::Read("not enough hex chars\\x1\""));
338 EXPECT_FALSE(JSONReader::Read("\"not enough escape chars\\u123\""));
339 EXPECT_FALSE(JSONReader::Read("\"extra backslash at end of input\\\""));
340 }
341
TEST_P(JSONReaderTest,BasicArray)342 TEST_P(JSONReaderTest, BasicArray) {
343 std::optional<Value> root = JSONReader::Read("[true, false, null]");
344 ASSERT_TRUE(root);
345 Value::List* list = root->GetIfList();
346 ASSERT_TRUE(list);
347 EXPECT_EQ(3U, list->size());
348
349 // Test with trailing comma. Should be parsed the same as above.
350 std::optional<Value> root2 =
351 JSONReader::Read("[true, false, null, ]", JSON_ALLOW_TRAILING_COMMAS);
352 ASSERT_TRUE(root2);
353 EXPECT_EQ(*list, *root2);
354 }
355
TEST_P(JSONReaderTest,EmptyArray)356 TEST_P(JSONReaderTest, EmptyArray) {
357 std::optional<Value> value = JSONReader::Read("[]");
358 ASSERT_TRUE(value);
359 Value::List* list = value->GetIfList();
360 ASSERT_TRUE(list);
361 EXPECT_TRUE(list->empty());
362 }
363
TEST_P(JSONReaderTest,CompleteArray)364 TEST_P(JSONReaderTest, CompleteArray) {
365 std::optional<Value> value = JSONReader::Read("[\"a\", 3, 4.56, null]");
366 ASSERT_TRUE(value);
367 Value::List* list = value->GetIfList();
368 ASSERT_TRUE(list);
369 EXPECT_EQ(4U, list->size());
370 }
371
TEST_P(JSONReaderTest,NestedArrays)372 TEST_P(JSONReaderTest, NestedArrays) {
373 std::optional<Value> value = JSONReader::Read(
374 "[[true], [], {\"smell\": \"nice\",\"taste\": \"yummy\" }, [false, [], "
375 "[null]], null]");
376 ASSERT_TRUE(value);
377 Value::List* list = value->GetIfList();
378 ASSERT_TRUE(list);
379 EXPECT_EQ(5U, list->size());
380
381 // Lots of trailing commas.
382 std::optional<Value> root2 = JSONReader::Read(
383 "[[true], [], {\"smell\": \"nice\",\"taste\": \"yummy\" }, [false, [], "
384 "[null, ] , ], null,]",
385 JSON_ALLOW_TRAILING_COMMAS);
386 ASSERT_TRUE(root2);
387 EXPECT_EQ(*list, *root2);
388 }
389
TEST_P(JSONReaderTest,InvalidArrays)390 TEST_P(JSONReaderTest, InvalidArrays) {
391 // Missing close brace.
392 EXPECT_FALSE(JSONReader::Read("[[true], [], [false, [], [null]], null"));
393
394 // Too many commas.
395 EXPECT_FALSE(JSONReader::Read("[true,, null]"));
396 EXPECT_FALSE(JSONReader::Read("[true,, null]", JSON_ALLOW_TRAILING_COMMAS));
397
398 // No commas.
399 EXPECT_FALSE(JSONReader::Read("[true null]"));
400
401 // Trailing comma.
402 EXPECT_FALSE(JSONReader::Read("[true,]"));
403 }
404
TEST_P(JSONReaderTest,ArrayTrailingComma)405 TEST_P(JSONReaderTest, ArrayTrailingComma) {
406 // Valid if we set |allow_trailing_comma| to true.
407 std::optional<Value> value =
408 JSONReader::Read("[true,]", JSON_ALLOW_TRAILING_COMMAS);
409 ASSERT_TRUE(value);
410 Value::List* list = value->GetIfList();
411 ASSERT_TRUE(list);
412 ASSERT_EQ(1U, list->size());
413 const Value& value1 = (*list)[0];
414 ASSERT_TRUE(value1.is_bool());
415 EXPECT_TRUE(value1.GetBool());
416 }
417
TEST_P(JSONReaderTest,ArrayTrailingCommaNoEmptyElements)418 TEST_P(JSONReaderTest, ArrayTrailingCommaNoEmptyElements) {
419 // Don't allow empty elements, even if |allow_trailing_comma| is
420 // true.
421 EXPECT_FALSE(JSONReader::Read("[,]", JSON_ALLOW_TRAILING_COMMAS));
422 EXPECT_FALSE(JSONReader::Read("[true,,]", JSON_ALLOW_TRAILING_COMMAS));
423 EXPECT_FALSE(JSONReader::Read("[,true,]", JSON_ALLOW_TRAILING_COMMAS));
424 EXPECT_FALSE(JSONReader::Read("[true,,false]", JSON_ALLOW_TRAILING_COMMAS));
425 }
426
TEST_P(JSONReaderTest,EmptyDictionary)427 TEST_P(JSONReaderTest, EmptyDictionary) {
428 std::optional<Value> dict_val = JSONReader::Read("{}");
429 ASSERT_TRUE(dict_val);
430 ASSERT_TRUE(dict_val->is_dict());
431 }
432
TEST_P(JSONReaderTest,CompleteDictionary)433 TEST_P(JSONReaderTest, CompleteDictionary) {
434 std::optional<Value> root1 = JSONReader::Read(
435 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", \"bool\": "
436 "false, \"more\": {} }");
437 ASSERT_TRUE(root1);
438 const Value::Dict* root1_dict = root1->GetIfDict();
439 ASSERT_TRUE(root1_dict);
440 auto double_val = root1_dict->FindDouble("number");
441 ASSERT_TRUE(double_val);
442 EXPECT_DOUBLE_EQ(9.87654321, *double_val);
443 const Value* null_val = root1_dict->Find("null");
444 ASSERT_TRUE(null_val);
445 EXPECT_TRUE(null_val->is_none());
446 const std::string* str_val = root1_dict->FindString("S");
447 ASSERT_TRUE(str_val);
448 EXPECT_EQ("str", *str_val);
449 auto bool_val = root1_dict->FindBool("bool");
450 ASSERT_TRUE(bool_val);
451 ASSERT_FALSE(*bool_val);
452
453 std::optional<Value> root2 = JSONReader::Read(
454 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", \"bool\": "
455 "false, \"more\": {},}",
456 JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
457 ASSERT_TRUE(root2);
458 Value::Dict* root2_dict = root2->GetIfDict();
459 ASSERT_TRUE(root2_dict);
460 EXPECT_EQ(*root1_dict, *root2_dict);
461
462 // Test newline equivalence.
463 root2 = JSONReader::Read(
464 "{\n"
465 " \"number\":9.87654321,\n"
466 " \"null\":null,\n"
467 " \"\\x53\":\"str\",\n"
468 " \"bool\": false,\n"
469 " \"more\": {},\n"
470 "}\n",
471 JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
472 ASSERT_TRUE(root2);
473 root2_dict = root2->GetIfDict();
474 ASSERT_TRUE(root2);
475 EXPECT_EQ(*root1_dict, *root2_dict);
476
477 root2 = JSONReader::Read(
478 "{\r\n"
479 " \"number\":9.87654321,\r\n"
480 " \"null\":null,\r\n"
481 " \"\\x53\":\"str\",\r\n"
482 " \"bool\": false,\r\n"
483 " \"more\": {},\r\n"
484 "}\r\n",
485 JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
486 ASSERT_TRUE(root2);
487 root2_dict = root2->GetIfDict();
488 ASSERT_TRUE(root2_dict);
489 EXPECT_EQ(*root1_dict, *root2_dict);
490 }
491
TEST_P(JSONReaderTest,NestedDictionaries)492 TEST_P(JSONReaderTest, NestedDictionaries) {
493 std::optional<Value> root1 = JSONReader::Read(
494 "{\"inner\":{\"array\":[true, 3, 4.56, null]},\"false\":false,\"d\":{}}");
495 ASSERT_TRUE(root1);
496 const base::Value::Dict* root1_dict = root1->GetIfDict();
497 ASSERT_TRUE(root1_dict);
498 const Value::Dict* inner_dict = root1_dict->FindDict("inner");
499 ASSERT_TRUE(inner_dict);
500 const Value::List* inner_array = inner_dict->FindList("array");
501 ASSERT_TRUE(inner_array);
502 EXPECT_EQ(4U, inner_array->size());
503 auto bool_value = root1_dict->FindBool("false");
504 ASSERT_TRUE(bool_value);
505 EXPECT_FALSE(*bool_value);
506 inner_dict = root1_dict->FindDict("d");
507 EXPECT_TRUE(inner_dict);
508
509 std::optional<Value> root2 = JSONReader::Read(
510 "{\"inner\": {\"array\":[true, 3, 4.56, null] , "
511 "},\"false\":false,\"d\":{},}",
512 JSON_ALLOW_TRAILING_COMMAS);
513 ASSERT_TRUE(root2);
514 EXPECT_EQ(*root1_dict, *root2);
515 }
516
TEST_P(JSONReaderTest,DictionaryKeysWithPeriods)517 TEST_P(JSONReaderTest, DictionaryKeysWithPeriods) {
518 std::optional<Value> root =
519 JSONReader::Read("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}");
520 ASSERT_TRUE(root);
521 Value::Dict* root_dict = root->GetIfDict();
522 ASSERT_TRUE(root_dict);
523
524 auto integer_value = root_dict->FindInt("a.b");
525 ASSERT_TRUE(integer_value);
526 EXPECT_EQ(3, *integer_value);
527 integer_value = root_dict->FindInt("c");
528 ASSERT_TRUE(integer_value);
529 EXPECT_EQ(2, *integer_value);
530 const Value::Dict* inner_dict = root_dict->FindDict("d.e.f");
531 ASSERT_TRUE(inner_dict);
532 EXPECT_EQ(1U, inner_dict->size());
533 integer_value = inner_dict->FindInt("g.h.i.j");
534 ASSERT_TRUE(integer_value);
535 EXPECT_EQ(1, *integer_value);
536
537 root = JSONReader::Read("{\"a\":{\"b\":2},\"a.b\":1}");
538 ASSERT_TRUE(root);
539 root_dict = root->GetIfDict();
540 ASSERT_TRUE(root_dict);
541 const Value* integer_path_value = root_dict->FindByDottedPath("a.b");
542 ASSERT_TRUE(integer_path_value);
543 EXPECT_EQ(2, integer_path_value->GetInt());
544 integer_value = root_dict->FindInt("a.b");
545 ASSERT_TRUE(integer_value);
546 EXPECT_EQ(1, *integer_value);
547 }
548
TEST_P(JSONReaderTest,DuplicateKeys)549 TEST_P(JSONReaderTest, DuplicateKeys) {
550 std::optional<Value> root = JSONReader::Read("{\"x\":1,\"x\":2,\"y\":3}");
551 ASSERT_TRUE(root);
552 const Value::Dict* root_dict = root->GetIfDict();
553 ASSERT_TRUE(root_dict);
554
555 auto integer_value = root_dict->FindInt("x");
556 ASSERT_TRUE(integer_value);
557 EXPECT_EQ(2, *integer_value);
558 }
559
TEST_P(JSONReaderTest,InvalidDictionaries)560 TEST_P(JSONReaderTest, InvalidDictionaries) {
561 // No closing brace.
562 EXPECT_FALSE(JSONReader::Read("{\"a\": true"));
563
564 // Keys must be quoted strings.
565 EXPECT_FALSE(JSONReader::Read("{foo:true}"));
566 EXPECT_FALSE(JSONReader::Read("{1234: false}"));
567 EXPECT_FALSE(JSONReader::Read("{:false}"));
568 EXPECT_FALSE(JSONReader::Read("{ , }"));
569
570 // Trailing comma.
571 EXPECT_FALSE(JSONReader::Read("{\"a\":true,}"));
572
573 // Too many commas.
574 EXPECT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}"));
575 EXPECT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}",
576 JSON_ALLOW_TRAILING_COMMAS));
577
578 // No separator.
579 EXPECT_FALSE(JSONReader::Read("{\"a\" \"b\"}"));
580
581 // Lone comma.
582 EXPECT_FALSE(JSONReader::Read("{,}"));
583 EXPECT_FALSE(JSONReader::Read("{,}", JSON_ALLOW_TRAILING_COMMAS));
584 EXPECT_FALSE(JSONReader::Read("{\"a\":true,,}", JSON_ALLOW_TRAILING_COMMAS));
585 EXPECT_FALSE(JSONReader::Read("{,\"a\":true}", JSON_ALLOW_TRAILING_COMMAS));
586 EXPECT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}",
587 JSON_ALLOW_TRAILING_COMMAS));
588 }
589
TEST_P(JSONReaderTest,StackOverflow)590 TEST_P(JSONReaderTest, StackOverflow) {
591 std::string evil(1000000, '[');
592 evil.append(std::string(1000000, ']'));
593 EXPECT_FALSE(JSONReader::Read(evil));
594
595 // A few thousand adjacent lists is fine.
596 std::string not_evil("[");
597 not_evil.reserve(15010);
598 for (int i = 0; i < 5000; ++i)
599 not_evil.append("[],");
600 not_evil.append("[]]");
601 std::optional<Value> value = JSONReader::Read(not_evil);
602 ASSERT_TRUE(value);
603 Value::List* list = value->GetIfList();
604 ASSERT_TRUE(list);
605 EXPECT_EQ(5001U, list->size());
606 }
607
TEST_P(JSONReaderTest,UTF8Input)608 TEST_P(JSONReaderTest, UTF8Input) {
609 std::optional<Value> root = JSONReader::Read("\"\xe7\xbd\x91\xe9\xa1\xb5\"");
610 ASSERT_TRUE(root);
611 ASSERT_TRUE(root->is_string());
612 const std::string& str_val = root->GetString();
613 EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val));
614
615 root = JSONReader::Read("{\"path\": \"/tmp/\xc3\xa0\xc3\xa8\xc3\xb2.png\"}");
616 ASSERT_TRUE(root);
617 const Value::Dict* root_dict = root->GetIfDict();
618 ASSERT_TRUE(root_dict);
619 const std::string* maybe_string = root_dict->FindString("path");
620 ASSERT_TRUE(maybe_string);
621 EXPECT_EQ("/tmp/\xC3\xA0\xC3\xA8\xC3\xB2.png", *maybe_string);
622
623 // JSON can encode non-characters.
624 const char* const noncharacters[] = {
625 "\"\xEF\xB7\x90\"", // U+FDD0
626 "\"\xEF\xB7\x9F\"", // U+FDDF
627 "\"\xEF\xB7\xAF\"", // U+FDEF
628 "\"\xEF\xBF\xBE\"", // U+FFFE
629 "\"\xEF\xBF\xBF\"", // U+FFFF
630 "\"\xF0\x9F\xBF\xBE\"", // U+01FFFE
631 "\"\xF0\x9F\xBF\xBF\"", // U+01FFFF
632 "\"\xF0\xAF\xBF\xBE\"", // U+02FFFE
633 "\"\xF0\xAF\xBF\xBF\"", // U+02FFFF
634 "\"\xF0\xBF\xBF\xBE\"", // U+03FFFE
635 "\"\xF0\xBF\xBF\xBF\"", // U+03FFFF
636 "\"\xF1\x8F\xBF\xBE\"", // U+04FFFE
637 "\"\xF1\x8F\xBF\xBF\"", // U+04FFFF
638 "\"\xF1\x9F\xBF\xBE\"", // U+05FFFE
639 "\"\xF1\x9F\xBF\xBF\"", // U+05FFFF
640 "\"\xF1\xAF\xBF\xBE\"", // U+06FFFE
641 "\"\xF1\xAF\xBF\xBF\"", // U+06FFFF
642 "\"\xF1\xBF\xBF\xBE\"", // U+07FFFE
643 "\"\xF1\xBF\xBF\xBF\"", // U+07FFFF
644 "\"\xF2\x8F\xBF\xBE\"", // U+08FFFE
645 "\"\xF2\x8F\xBF\xBF\"", // U+08FFFF
646 "\"\xF2\x9F\xBF\xBE\"", // U+09FFFE
647 "\"\xF2\x9F\xBF\xBF\"", // U+09FFFF
648 "\"\xF2\xAF\xBF\xBE\"", // U+0AFFFE
649 "\"\xF2\xAF\xBF\xBF\"", // U+0AFFFF
650 "\"\xF2\xBF\xBF\xBE\"", // U+0BFFFE
651 "\"\xF2\xBF\xBF\xBF\"", // U+0BFFFF
652 "\"\xF3\x8F\xBF\xBE\"", // U+0CFFFE
653 "\"\xF3\x8F\xBF\xBF\"", // U+0CFFFF
654 "\"\xF3\x9F\xBF\xBE\"", // U+0DFFFE
655 "\"\xF3\x9F\xBF\xBF\"", // U+0DFFFF
656 "\"\xF3\xAF\xBF\xBE\"", // U+0EFFFE
657 "\"\xF3\xAF\xBF\xBF\"", // U+0EFFFF
658 "\"\xF3\xBF\xBF\xBE\"", // U+0FFFFE
659 "\"\xF3\xBF\xBF\xBF\"", // U+0FFFFF
660 "\"\xF4\x8F\xBF\xBE\"", // U+10FFFE
661 "\"\xF4\x8F\xBF\xBF\"", // U+10FFFF
662 };
663 for (auto* noncharacter : noncharacters) {
664 root = JSONReader::Read(noncharacter);
665 ASSERT_TRUE(root);
666 ASSERT_TRUE(root->is_string());
667 EXPECT_EQ(std::string(noncharacter + 1, strlen(noncharacter) - 2),
668 root->GetString());
669 }
670 }
671
TEST_P(JSONReaderTest,InvalidUTF8Input)672 TEST_P(JSONReaderTest, InvalidUTF8Input) {
673 EXPECT_FALSE(JSONReader::Read("\"345\xb0\xa1\xb0\xa2\""));
674 EXPECT_FALSE(JSONReader::Read("\"123\xc0\x81\""));
675 EXPECT_FALSE(JSONReader::Read("\"abc\xc0\xae\""));
676 }
677
TEST_P(JSONReaderTest,UTF16Escapes)678 TEST_P(JSONReaderTest, UTF16Escapes) {
679 std::optional<Value> root = JSONReader::Read("\"\\u20ac3,14\"");
680 ASSERT_TRUE(root);
681 ASSERT_TRUE(root->is_string());
682 EXPECT_EQ(
683 "\xe2\x82\xac"
684 "3,14",
685 root->GetString());
686
687 root = JSONReader::Read("\"\\ud83d\\udca9\\ud83d\\udc6c\"");
688 ASSERT_TRUE(root);
689 ASSERT_TRUE(root->is_string());
690 EXPECT_EQ("\xf0\x9f\x92\xa9\xf0\x9f\x91\xac", root->GetString());
691 }
692
TEST_P(JSONReaderTest,InvalidUTF16Escapes)693 TEST_P(JSONReaderTest, InvalidUTF16Escapes) {
694 const char* const cases[] = {
695 "\"\\u123\"", // Invalid scalar.
696 "\"\\ud83d\"", // Invalid scalar.
697 "\"\\u$%@!\"", // Invalid scalar.
698 "\"\\uzz89\"", // Invalid scalar.
699 "\"\\ud83d\\udca\"", // Invalid lower surrogate.
700 "\"\\ud83d\\ud83d\"", // Invalid lower surrogate.
701 "\"\\ud83d\\uaaaZ\"", // Invalid lower surrogate.
702 "\"\\ud83foo\"", // No lower surrogate.
703 "\"\\ud83d\\foo\"", // No lower surrogate.
704 "\"\\ud83\\foo\"", // Invalid upper surrogate.
705 "\"\\ud83d\\u1\"", // No lower surrogate.
706 "\"\\ud83\\u1\"", // Invalid upper surrogate.
707 };
708 std::optional<Value> root;
709 for (auto* i : cases) {
710 root = JSONReader::Read(i);
711 EXPECT_FALSE(root) << i;
712 }
713 }
714
TEST_P(JSONReaderTest,LiteralRoots)715 TEST_P(JSONReaderTest, LiteralRoots) {
716 std::optional<Value> root = JSONReader::Read("null");
717 ASSERT_TRUE(root);
718 EXPECT_TRUE(root->is_none());
719
720 root = JSONReader::Read("true");
721 ASSERT_TRUE(root);
722 ASSERT_TRUE(root->is_bool());
723 EXPECT_TRUE(root->GetBool());
724
725 root = JSONReader::Read("10");
726 ASSERT_TRUE(root);
727 ASSERT_TRUE(root->is_int());
728 EXPECT_EQ(10, root->GetInt());
729
730 root = JSONReader::Read("\"root\"");
731 ASSERT_TRUE(root);
732 ASSERT_TRUE(root->is_string());
733 EXPECT_EQ("root", root->GetString());
734 }
735
TEST_P(JSONReaderTest,ReadFromFile)736 TEST_P(JSONReaderTest, ReadFromFile) {
737 FilePath path;
738 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &path));
739 path = path.AppendASCII("json");
740 ASSERT_TRUE(base::PathExists(path));
741
742 std::string input;
743 ASSERT_TRUE(ReadFileToString(path.AppendASCII("bom_feff.json"), &input));
744
745 EXPECT_THAT(
746 JSONReader::ReadAndReturnValueWithError(input),
747 base::test::ValueIs(::testing::Property(&base::Value::is_dict, true)));
748 }
749
750 // Tests that the root of a JSON object can be deleted safely while its
751 // children outlive it.
TEST_P(JSONReaderTest,StringOptimizations)752 TEST_P(JSONReaderTest, StringOptimizations) {
753 Value dict_literal_0;
754 Value dict_literal_1;
755 Value dict_string_0;
756 Value dict_string_1;
757 Value list_value_0;
758 Value list_value_1;
759
760 {
761 std::optional<Value> root = JSONReader::Read(
762 "{"
763 " \"test\": {"
764 " \"foo\": true,"
765 " \"bar\": 3.14,"
766 " \"baz\": \"bat\","
767 " \"moo\": \"cow\""
768 " },"
769 " \"list\": ["
770 " \"a\","
771 " \"b\""
772 " ]"
773 "}",
774 JSON_PARSE_RFC);
775 ASSERT_TRUE(root);
776 Value::Dict* root_dict = root->GetIfDict();
777 ASSERT_TRUE(root_dict);
778
779 Value::Dict* dict = root_dict->FindDict("test");
780 ASSERT_TRUE(dict);
781 Value::List* list = root_dict->FindList("list");
782 ASSERT_TRUE(list);
783
784 Value* to_move = dict->Find("foo");
785 ASSERT_TRUE(to_move);
786 dict_literal_0 = std::move(*to_move);
787 to_move = dict->Find("bar");
788 ASSERT_TRUE(to_move);
789 dict_literal_1 = std::move(*to_move);
790 to_move = dict->Find("baz");
791 ASSERT_TRUE(to_move);
792 dict_string_0 = std::move(*to_move);
793 to_move = dict->Find("moo");
794 ASSERT_TRUE(to_move);
795 dict_string_1 = std::move(*to_move);
796 ASSERT_TRUE(dict->Remove("foo"));
797 ASSERT_TRUE(dict->Remove("bar"));
798 ASSERT_TRUE(dict->Remove("baz"));
799 ASSERT_TRUE(dict->Remove("moo"));
800
801 ASSERT_EQ(2u, list->size());
802 list_value_0 = std::move((*list)[0]);
803 list_value_1 = std::move((*list)[1]);
804 list->clear();
805 }
806
807 ASSERT_TRUE(dict_literal_0.is_bool());
808 EXPECT_TRUE(dict_literal_0.GetBool());
809
810 ASSERT_TRUE(dict_literal_1.is_double());
811 EXPECT_EQ(3.14, dict_literal_1.GetDouble());
812
813 ASSERT_TRUE(dict_string_0.is_string());
814 EXPECT_EQ("bat", dict_string_0.GetString());
815
816 ASSERT_TRUE(dict_string_1.is_string());
817 EXPECT_EQ("cow", dict_string_1.GetString());
818
819 ASSERT_TRUE(list_value_0.is_string());
820 EXPECT_EQ("a", list_value_0.GetString());
821 ASSERT_TRUE(list_value_1.is_string());
822 EXPECT_EQ("b", list_value_1.GetString());
823 }
824
825 // A smattering of invalid JSON designed to test specific portions of the
826 // parser implementation against buffer overflow. Best run with DCHECKs so
827 // that the one in NextChar fires.
TEST_P(JSONReaderTest,InvalidSanity)828 TEST_P(JSONReaderTest, InvalidSanity) {
829 const char* const kInvalidJson[] = {
830 "/* test *", "{\"foo\"", "{\"foo\":", " [", "\"\\u123g\"", "{\n\"eh:\n}",
831 };
832
833 for (size_t i = 0; i < std::size(kInvalidJson); ++i) {
834 LOG(INFO) << "Sanity test " << i << ": <" << kInvalidJson[i] << ">";
835 auto root = JSONReader::ReadAndReturnValueWithError(kInvalidJson[i]);
836 EXPECT_FALSE(root.has_value());
837 EXPECT_NE("", root.error().message);
838 }
839 }
840
TEST_P(JSONReaderTest,IllegalTrailingNull)841 TEST_P(JSONReaderTest, IllegalTrailingNull) {
842 const char json[] = {'"', 'n', 'u', 'l', 'l', '"', '\0'};
843 std::string json_string(json, sizeof(json));
844 auto root = JSONReader::ReadAndReturnValueWithError(json_string);
845 EXPECT_FALSE(root.has_value());
846 EXPECT_NE("", root.error().message);
847 }
848
TEST_P(JSONReaderTest,ASCIIControlCodes)849 TEST_P(JSONReaderTest, ASCIIControlCodes) {
850 // A literal NUL byte or a literal new line, in a JSON string, should be
851 // rejected. RFC 8259 section 7 says "the characters that MUST be escaped
852 // [include]... the control characters (U+0000 through U+001F)".
853 //
854 // Currently, we accept \r and \n in JSON strings because they are widely used
855 // and somewhat useful (especially when nesting JSON messages), but reject all
856 // other control characters.
857 {
858 const char json[] = "\"a\rn\nc\"";
859 auto root = JSONReader::Read(json);
860 ASSERT_TRUE(root);
861 ASSERT_TRUE(root->is_string());
862 EXPECT_EQ(5u, root->GetString().length());
863 }
864
865 {
866 // Replace the \r with a disallowed \f, and require parsing to fail:
867 const char json[] = "\"a\fn\nc\"";
868 auto root = JSONReader::ReadAndReturnValueWithError(json);
869 EXPECT_FALSE(root.has_value());
870 EXPECT_NE("", root.error().message);
871 }
872 }
873
TEST_P(JSONReaderTest,MaxNesting)874 TEST_P(JSONReaderTest, MaxNesting) {
875 std::string json(R"({"outer": { "inner": {"foo": true}}})");
876 EXPECT_FALSE(JSONReader::Read(json, JSON_PARSE_RFC, 3));
877 EXPECT_TRUE(JSONReader::Read(json, JSON_PARSE_RFC, 4));
878 }
879
TEST_P(JSONReaderTest,Decode4ByteUtf8Char)880 TEST_P(JSONReaderTest, Decode4ByteUtf8Char) {
881 // kUtf8Data contains a 4 byte unicode character (a smiley!) that JSONReader
882 // should be able to handle. The UTF-8 encoding of U+1F607 SMILING FACE WITH
883 // HALO is "\xF0\x9F\x98\x87".
884 const char kUtf8Data[] = "[\"\",[],[],[],{\"google:suggesttype\":[]}]";
885 std::optional<Value> root = JSONReader::Read(kUtf8Data, JSON_PARSE_RFC);
886 ASSERT_TRUE(root);
887 Value::List* list = root->GetIfList();
888 ASSERT_TRUE(list);
889 ASSERT_EQ(5u, list->size());
890 ASSERT_TRUE((*list)[0].is_string());
891 EXPECT_EQ("\xF0\x9F\x98\x87", (*list)[0].GetString());
892 }
893
TEST_P(JSONReaderTest,DecodeUnicodeNonCharacter)894 TEST_P(JSONReaderTest, DecodeUnicodeNonCharacter) {
895 // Tests Unicode code points (encoded as escaped UTF-16) that are not valid
896 // characters.
897 EXPECT_TRUE(JSONReader::Read("[\"\\uFDD0\"]")); // U+FDD0
898 EXPECT_TRUE(JSONReader::Read("[\"\\uFDDF\"]")); // U+FDDF
899 EXPECT_TRUE(JSONReader::Read("[\"\\uFDEF\"]")); // U+FDEF
900 EXPECT_TRUE(JSONReader::Read("[\"\\uFFFE\"]")); // U+FFFE
901 EXPECT_TRUE(JSONReader::Read("[\"\\uFFFF\"]")); // U+FFFF
902 EXPECT_TRUE(JSONReader::Read("[\"\\uD83F\\uDFFE\"]")); // U+01FFFE
903 EXPECT_TRUE(JSONReader::Read("[\"\\uD83F\\uDFFF\"]")); // U+01FFFF
904 EXPECT_TRUE(JSONReader::Read("[\"\\uD87F\\uDFFE\"]")); // U+02FFFE
905 EXPECT_TRUE(JSONReader::Read("[\"\\uD87F\\uDFFF\"]")); // U+02FFFF
906 EXPECT_TRUE(JSONReader::Read("[\"\\uD8BF\\uDFFE\"]")); // U+03FFFE
907 EXPECT_TRUE(JSONReader::Read("[\"\\uD8BF\\uDFFF\"]")); // U+03FFFF
908 EXPECT_TRUE(JSONReader::Read("[\"\\uD8FF\\uDFFE\"]")); // U+04FFFE
909 EXPECT_TRUE(JSONReader::Read("[\"\\uD8FF\\uDFFF\"]")); // U+04FFFF
910 EXPECT_TRUE(JSONReader::Read("[\"\\uD93F\\uDFFE\"]")); // U+05FFFE
911 EXPECT_TRUE(JSONReader::Read("[\"\\uD93F\\uDFFF\"]")); // U+05FFFF
912 EXPECT_TRUE(JSONReader::Read("[\"\\uD97F\\uDFFE\"]")); // U+06FFFE
913 EXPECT_TRUE(JSONReader::Read("[\"\\uD97F\\uDFFF\"]")); // U+06FFFF
914 EXPECT_TRUE(JSONReader::Read("[\"\\uD9BF\\uDFFE\"]")); // U+07FFFE
915 EXPECT_TRUE(JSONReader::Read("[\"\\uD9BF\\uDFFF\"]")); // U+07FFFF
916 EXPECT_TRUE(JSONReader::Read("[\"\\uD9FF\\uDFFE\"]")); // U+08FFFE
917 EXPECT_TRUE(JSONReader::Read("[\"\\uD9FF\\uDFFF\"]")); // U+08FFFF
918 EXPECT_TRUE(JSONReader::Read("[\"\\uDA3F\\uDFFE\"]")); // U+09FFFE
919 EXPECT_TRUE(JSONReader::Read("[\"\\uDA3F\\uDFFF\"]")); // U+09FFFF
920 EXPECT_TRUE(JSONReader::Read("[\"\\uDA7F\\uDFFE\"]")); // U+0AFFFE
921 EXPECT_TRUE(JSONReader::Read("[\"\\uDA7F\\uDFFF\"]")); // U+0AFFFF
922 EXPECT_TRUE(JSONReader::Read("[\"\\uDABF\\uDFFE\"]")); // U+0BFFFE
923 EXPECT_TRUE(JSONReader::Read("[\"\\uDABF\\uDFFF\"]")); // U+0BFFFF
924 EXPECT_TRUE(JSONReader::Read("[\"\\uDAFF\\uDFFE\"]")); // U+0CFFFE
925 EXPECT_TRUE(JSONReader::Read("[\"\\uDAFF\\uDFFF\"]")); // U+0CFFFF
926 EXPECT_TRUE(JSONReader::Read("[\"\\uDB3F\\uDFFE\"]")); // U+0DFFFE
927 EXPECT_TRUE(JSONReader::Read("[\"\\uDB3F\\uDFFF\"]")); // U+0DFFFF
928 EXPECT_TRUE(JSONReader::Read("[\"\\uDB7F\\uDFFE\"]")); // U+0EFFFE
929 EXPECT_TRUE(JSONReader::Read("[\"\\uDB7F\\uDFFF\"]")); // U+0EFFFF
930 EXPECT_TRUE(JSONReader::Read("[\"\\uDBBF\\uDFFE\"]")); // U+0FFFFE
931 EXPECT_TRUE(JSONReader::Read("[\"\\uDBBF\\uDFFF\"]")); // U+0FFFFF
932 EXPECT_TRUE(JSONReader::Read("[\"\\uDBFF\\uDFFE\"]")); // U+10FFFE
933 EXPECT_TRUE(JSONReader::Read("[\"\\uDBFF\\uDFFF\"]")); // U+10FFFF
934 }
935
TEST_P(JSONReaderTest,DecodeNegativeEscapeSequence)936 TEST_P(JSONReaderTest, DecodeNegativeEscapeSequence) {
937 EXPECT_FALSE(JSONReader::Read("[\"\\x-A\"]"));
938 EXPECT_FALSE(JSONReader::Read("[\"\\u-00A\"]"));
939 }
940
941 // Verifies invalid code points are replaced.
TEST_P(JSONReaderTest,ReplaceInvalidCharacters)942 TEST_P(JSONReaderTest, ReplaceInvalidCharacters) {
943 // U+D800 is a lone high surrogate.
944 const std::string invalid_high = "\"\xED\xA0\x80\"";
945 std::optional<Value> value =
946 JSONReader::Read(invalid_high, JSON_REPLACE_INVALID_CHARACTERS);
947 ASSERT_TRUE(value);
948 ASSERT_TRUE(value->is_string());
949 // Expect three U+FFFD (one for each UTF-8 byte in the invalid code point).
950 EXPECT_EQ("\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD", value->GetString());
951
952 // U+DFFF is a lone low surrogate.
953 const std::string invalid_low = "\"\xED\xBF\xBF\"";
954 value = JSONReader::Read(invalid_low, JSON_REPLACE_INVALID_CHARACTERS);
955 ASSERT_TRUE(value);
956 ASSERT_TRUE(value->is_string());
957 // Expect three U+FFFD (one for each UTF-8 byte in the invalid code point).
958 EXPECT_EQ("\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD", value->GetString());
959 }
960
TEST_P(JSONReaderTest,ReplaceInvalidUTF16EscapeSequence)961 TEST_P(JSONReaderTest, ReplaceInvalidUTF16EscapeSequence) {
962 // U+D800 is a lone high surrogate.
963 const std::string invalid_high = "\"_\\uD800_\"";
964 std::optional<Value> value =
965 JSONReader::Read(invalid_high, JSON_REPLACE_INVALID_CHARACTERS);
966 ASSERT_TRUE(value);
967 ASSERT_TRUE(value->is_string());
968 EXPECT_EQ("_\xEF\xBF\xBD_", value->GetString());
969
970 // U+DFFF is a lone low surrogate.
971 const std::string invalid_low = "\"_\\uDFFF_\"";
972 value = JSONReader::Read(invalid_low, JSON_REPLACE_INVALID_CHARACTERS);
973 ASSERT_TRUE(value);
974 ASSERT_TRUE(value->is_string());
975 EXPECT_EQ("_\xEF\xBF\xBD_", value->GetString());
976 }
977
TEST_P(JSONReaderTest,ParseNumberErrors)978 TEST_P(JSONReaderTest, ParseNumberErrors) {
979 const struct {
980 const char* input;
981 bool parse_success;
982 double value;
983 } kCases[] = {
984 // clang-format off
985 {"1", true, 1},
986 {"2.", false, 0},
987 {"42", true, 42},
988 {"6e", false, 0},
989 {"43e2", true, 4300},
990 {"43e-", false, 0},
991 {"9e-3", true, 0.009},
992 {"2e+", false, 0},
993 {"2e+2", true, 200},
994 // clang-format on
995 };
996
997 for (unsigned int i = 0; i < std::size(kCases); ++i) {
998 auto test_case = kCases[i];
999 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case.input));
1000
1001 std::unique_ptr<char[]> input_owner;
1002 std::string_view input =
1003 MakeNotNullTerminatedInput(test_case.input, &input_owner);
1004
1005 std::optional<Value> result = JSONReader::Read(input);
1006 EXPECT_EQ(test_case.parse_success, result.has_value());
1007
1008 if (!result)
1009 continue;
1010
1011 ASSERT_TRUE(result->is_double() || result->is_int());
1012 EXPECT_EQ(test_case.value, result->GetDouble());
1013 }
1014 }
1015
TEST_P(JSONReaderTest,UnterminatedInputs)1016 TEST_P(JSONReaderTest, UnterminatedInputs) {
1017 const char* const kCases[] = {
1018 // clang-format off
1019 "/",
1020 "//",
1021 "/*",
1022 "\"xxxxxx",
1023 "\"",
1024 "{ ",
1025 "[\t",
1026 "tru",
1027 "fals",
1028 "nul",
1029 "\"\\x",
1030 "\"\\x2",
1031 "\"\\u123",
1032 "\"\\uD803\\u",
1033 "\"\\",
1034 "\"\\/",
1035 // clang-format on
1036 };
1037
1038 for (unsigned int i = 0; i < std::size(kCases); ++i) {
1039 auto* test_case = kCases[i];
1040 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case));
1041
1042 std::unique_ptr<char[]> input_owner;
1043 std::string_view input =
1044 MakeNotNullTerminatedInput(test_case, &input_owner);
1045
1046 EXPECT_FALSE(JSONReader::Read(input));
1047 }
1048 }
1049
TEST_P(JSONReaderTest,LineColumnCounting)1050 TEST_P(JSONReaderTest, LineColumnCounting) {
1051 const struct {
1052 const char* input;
1053 int error_line;
1054 int error_column;
1055 } kCases[] = {
1056 // For all but the "q_is_not_etc" case, the error (indicated by ^ in the
1057 // comments) is seeing a digit when expecting ',' or ']'.
1058 {
1059 // Line and column counts are 1-based, not 0-based.
1060 "q_is_not_the_start_of_any_valid_JSON_token",
1061 1,
1062 1,
1063 },
1064 {
1065 "[2,4,6 8",
1066 // -----^
1067 1,
1068 8,
1069 },
1070 {
1071 "[2,4,6\t8",
1072 // ------^
1073 1,
1074 8,
1075 },
1076 {
1077 "[2,4,6\n8",
1078 // ------^
1079 2,
1080 1,
1081 },
1082 {
1083 "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]",
1084 // ---------------------^
1085 5,
1086 9,
1087 },
1088 {
1089 // Same as the previous example, but with "\r\n"s instead of "\n"s.
1090 "[\r\n0,\r\n1,\r\n2,\r\n3,4,5,6 7,\r\n8,\r\n9\r\n]",
1091 // -----------------------------^
1092 5,
1093 9,
1094 },
1095 // The JSON spec forbids unescaped ASCII control characters (including
1096 // line breaks) within a string, but our implementation is more lenient.
1097 {
1098 "[\"3\n1\" 4",
1099 // --------^
1100 2,
1101 4,
1102 },
1103 {
1104 "[\"3\r\n1\" 4",
1105 // ----------^
1106 2,
1107 4,
1108 },
1109 };
1110
1111 for (unsigned int i = 0; i < std::size(kCases); ++i) {
1112 auto test_case = kCases[i];
1113 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case.input));
1114
1115 auto root = JSONReader::ReadAndReturnValueWithError(
1116 test_case.input, JSON_PARSE_RFC | JSON_ALLOW_NEWLINES_IN_STRINGS);
1117 EXPECT_FALSE(root.has_value());
1118 EXPECT_EQ(test_case.error_line, root.error().line);
1119 EXPECT_EQ(test_case.error_column, root.error().column);
1120 }
1121 }
1122
TEST_P(JSONReaderTest,ChromiumExtensions)1123 TEST_P(JSONReaderTest, ChromiumExtensions) {
1124 // All of these cases should parse with JSON_PARSE_CHROMIUM_EXTENSIONS but
1125 // fail with JSON_PARSE_RFC.
1126 const struct {
1127 // The JSON input.
1128 const char* input;
1129 // What JSON_* option permits this extension.
1130 int option;
1131 } kCases[] = {
1132 {"{ /* comment */ \"foo\": 3 }", JSON_ALLOW_COMMENTS},
1133 {"{ // comment\n \"foo\": 3 }", JSON_ALLOW_COMMENTS},
1134 {"[\"\\xAB\"]", JSON_ALLOW_X_ESCAPES},
1135 {"[\"\n\"]", JSON_ALLOW_NEWLINES_IN_STRINGS},
1136 {"[\"\r\"]", JSON_ALLOW_NEWLINES_IN_STRINGS},
1137 };
1138
1139 for (size_t i = 0; i < std::size(kCases); ++i) {
1140 SCOPED_TRACE(testing::Message() << "case " << i);
1141 const auto& test_case = kCases[i];
1142
1143 auto result = JSONReader::ReadAndReturnValueWithError(test_case.input,
1144 JSON_PARSE_RFC);
1145 EXPECT_FALSE(result.has_value());
1146
1147 result = JSONReader::ReadAndReturnValueWithError(
1148 test_case.input, JSON_PARSE_RFC | test_case.option);
1149 EXPECT_TRUE(result.has_value());
1150
1151 result = JSONReader::ReadAndReturnValueWithError(
1152 test_case.input, JSON_PARSE_CHROMIUM_EXTENSIONS);
1153 EXPECT_TRUE(result.has_value());
1154
1155 result = JSONReader::ReadAndReturnValueWithError(
1156 test_case.input, JSON_PARSE_CHROMIUM_EXTENSIONS & ~test_case.option);
1157 EXPECT_FALSE(result.has_value());
1158 }
1159 }
1160
1161 // For every control character, place it unescaped in a string and ensure that:
1162 // a) It doesn't parse with JSON_PARSE_RFC
1163 // b) It doesn't parse with JSON_PARSE_CHROMIUM_EXTENSIONS
1164 // c) It does parse with JSON_ALLOW_CONTROL_CHARS
TEST_P(JSONReaderTest,UnescapedControls)1165 TEST_P(JSONReaderTest, UnescapedControls) {
1166 std::string input = "\"foo\"";
1167 // ECMA-404 (JSON standard) section 9: characters from 0x00 to 0x1f must be
1168 // escaped.
1169 for (char c = 0x00; c <= 0x1f; c++) {
1170 input[1] = c;
1171
1172 auto result = JSONReader::Read(input, JSON_PARSE_RFC);
1173 EXPECT_FALSE(result.has_value());
1174
1175 bool should_parse_with_extensions = (c == '\r' || c == '\n');
1176 result = JSONReader::Read(input, JSON_PARSE_CHROMIUM_EXTENSIONS);
1177 EXPECT_EQ(should_parse_with_extensions, result.has_value());
1178
1179 result = JSONReader::Read(input, JSON_ALLOW_CONTROL_CHARS);
1180 ASSERT_TRUE(result.has_value());
1181 ASSERT_TRUE(result->is_string());
1182 EXPECT_EQ(result->GetString().length(), input.length() - 2);
1183 EXPECT_EQ(result->GetString()[0], c);
1184 }
1185 }
1186
TEST_P(JSONReaderTest,UsingRust)1187 TEST_P(JSONReaderTest, UsingRust) {
1188 ASSERT_EQ(JSONReader::UsingRust(), using_rust_);
1189 }
1190
1191 INSTANTIATE_TEST_SUITE_P(All,
1192 JSONReaderTest,
1193 #if BUILDFLAG(BUILD_RUST_JSON_READER)
1194 testing::Bool(),
1195 #else // BUILDFLAG(BUILD_RUST_JSON_READER)
1196 testing::Values(false),
1197 #endif // BUILDFLAG(BUILD_RUST_JSON_READER)
__anon1805e2530502(const testing::TestParamInfo<bool>& info) 1198 [](const testing::TestParamInfo<bool>& info) {
1199 return info.param ? "Rust" : "Cpp";
1200 });
1201
1202 } // namespace base
1203