xref: /aosp_15_r20/external/cronet/base/json/json_reader_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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