json_stream_parser_test.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
32 
39 #include <gtest/gtest.h>
40 
42 
43 
44 namespace google {
45 namespace protobuf {
46 namespace util {
47 using util::Status;
48 namespace error {
50 } // namespace error
51 namespace converter {
52 
53 using util::Status;
54 
55 // Tests for the JSON Stream Parser. These tests are intended to be
56 // comprehensive and cover the following:
57 //
58 // Positive tests:
59 // - true, false, null
60 // - empty object or array.
61 // - negative and positive double and int, unsigned int
62 // - single and double quoted strings
63 // - string key, unquoted key, numeric key
64 // - array containing array, object, value
65 // - object containing array, object, value
66 // - unicode handling in strings
67 // - ascii escaping (\b, \f, \n, \r, \t, \v)
68 // - trailing commas
69 //
70 // Negative tests:
71 // - illegal literals
72 // - mismatched quotes failure on strings
73 // - unterminated string failure
74 // - unexpected end of string failure
75 // - mismatched object and array closing
76 // - Failure to close array or object
77 // - numbers too large
78 // - invalid unicode escapes.
79 // - invalid unicode sequences.
80 // - numbers as keys
81 //
82 // For each test we split the input string on every possible character to ensure
83 // the parser is able to handle arbitrarily split input for all cases. We also
84 // do a final test of the entire test case one character at a time.
85 //
86 // It is verified that expected calls to the mocked objects are in sequence.
88  protected:
90  virtual ~JsonStreamParserTest() {}
91 
92  util::Status RunTest(StringPiece json, int split,
93  bool coerce_utf8 = false, bool allow_empty_null = false,
94  bool loose_float_number_conversion = false) {
96 
97  // Special case for split == length, test parsing one character at a time.
98  if (split == json.length()) {
99  GOOGLE_LOG(INFO) << "Testing split every char: " << json;
100  for (int i = 0; i < json.length(); ++i) {
101  StringPiece single = json.substr(i, 1);
102  util::Status result = parser.Parse(single);
103  if (!result.ok()) {
104  return result;
105  }
106  }
107  return parser.FinishParse();
108  }
109 
110  // Normal case, split at the split point and parse two substrings.
111  StringPiece first = json.substr(0, split);
112  StringPiece rest = json.substr(split);
113  GOOGLE_LOG(INFO) << "Testing split: " << first << "><" << rest;
114  util::Status result = parser.Parse(first);
115  if (result.ok()) {
116  result = parser.Parse(rest);
117  if (result.ok()) {
118  result = parser.FinishParse();
119  }
120  }
121  if (result.ok()) {
122  EXPECT_EQ(parser.recursion_depth(), 0);
123  }
124  return result;
125  }
126 
127  void DoTest(StringPiece json, int split, bool coerce_utf8 = false,
128  bool allow_empty_null = false,
129  bool loose_float_number_conversion = false) {
130  util::Status result = RunTest(json, split, coerce_utf8, allow_empty_null,
131  loose_float_number_conversion);
132  if (!result.ok()) {
133  GOOGLE_LOG(WARNING) << result;
134  }
135  EXPECT_OK(result);
136  }
137 
138  void DoErrorTest(StringPiece json, int split,
139  StringPiece error_prefix, bool coerce_utf8 = false,
140  bool allow_empty_null = false) {
141  util::Status result = RunTest(json, split, coerce_utf8, allow_empty_null);
143  StringPiece error_message(result.error_message());
144  EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
145  }
146 
147 
148 #ifndef _MSC_VER
149  // TODO(xiaofeng): We have to disable InSequence check for MSVC because it
150  // causes stack overflow due to its use of a linked list that is desctructed
151  // recursively.
152  ::testing::InSequence in_sequence_;
153 #endif // !_MSC_VER
156 };
157 
158 
159 // Positive tests
160 
161 // - true, false, null
163  StringPiece str = "true";
164  for (int i = 0; i <= str.length(); ++i) {
165  ow_.RenderBool("", true);
166  DoTest(str, i);
167  }
168 }
169 
171  StringPiece str = "false";
172  for (int i = 0; i <= str.length(); ++i) {
173  ow_.RenderBool("", false);
174  DoTest(str, i);
175  }
176 }
177 
179  StringPiece str = "null";
180  for (int i = 0; i <= str.length(); ++i) {
181  ow_.RenderNull("");
182  DoTest(str, i);
183  }
184 }
185 
186 // - empty object and array.
188  StringPiece str = "{}";
189  for (int i = 0; i <= str.length(); ++i) {
190  ow_.StartObject("")->EndObject();
191  DoTest(str, i);
192  }
193 }
194 
196  StringPiece str = "[]";
197  for (int i = 0; i <= str.length(); ++i) {
198  ow_.StartList("")->EndList();
199  DoTest(str, i);
200  }
201 }
202 
203 // - negative and positive double and int, unsigned int
204 TEST_F(JsonStreamParserTest, SimpleDouble) {
205  StringPiece str = "42.5";
206  for (int i = 0; i <= str.length(); ++i) {
207  ow_.RenderDouble("", 42.5);
208  DoTest(str, i);
209  }
210 }
211 
212 TEST_F(JsonStreamParserTest, ScientificDouble) {
213  StringPiece str = "1.2345e-10";
214  for (int i = 0; i < str.length(); ++i) {
215  ow_.RenderDouble("", 1.2345e-10);
216  DoTest(str, i);
217  }
218 }
219 
220 TEST_F(JsonStreamParserTest, SimpleNegativeDouble) {
221  StringPiece str = "-1045.235";
222  for (int i = 0; i <= str.length(); ++i) {
223  ow_.RenderDouble("", -1045.235);
224  DoTest(str, i);
225  }
226 }
227 
229  StringPiece str = "123456";
230  for (int i = 0; i <= str.length(); ++i) {
231  ow_.RenderUint64("", 123456);
232  DoTest(str, i);
233  }
234 }
235 
236 TEST_F(JsonStreamParserTest, SimpleNegativeInt) {
237  StringPiece str = "-79497823553162765";
238  for (int i = 0; i <= str.length(); ++i) {
239  ow_.RenderInt64("", -79497823553162765LL);
240  DoTest(str, i);
241  }
242 }
243 
244 TEST_F(JsonStreamParserTest, SimpleUnsignedInt) {
245  StringPiece str = "11779497823553162765";
246  for (int i = 0; i <= str.length(); ++i) {
247  ow_.RenderUint64("", 11779497823553162765ULL);
248  DoTest(str, i);
249  }
250 }
251 
252 TEST_F(JsonStreamParserTest, OctalNumberIsInvalid) {
253  StringPiece str = "01234";
254  for (int i = 0; i <= str.length(); ++i) {
255  DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
256  }
257  str = "-01234";
258  for (int i = 0; i <= str.length(); ++i) {
259  DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
260  }
261 }
262 
263 TEST_F(JsonStreamParserTest, HexNumberIsInvalid) {
264  StringPiece str = "0x1234";
265  for (int i = 0; i <= str.length(); ++i) {
266  DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
267  }
268  str = "-0x1234";
269  for (int i = 0; i <= str.length(); ++i) {
270  DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
271  }
272  str = "12x34";
273  for (int i = 0; i <= str.length(); ++i) {
274  DoErrorTest(str, i, "Unable to parse number.");
275  }
276 }
277 
278 // - single and double quoted strings
279 TEST_F(JsonStreamParserTest, EmptyDoubleQuotedString) {
280  StringPiece str = "\"\"";
281  for (int i = 0; i <= str.length(); ++i) {
282  ow_.RenderString("", "");
283  DoTest(str, i);
284  }
285 }
286 
287 TEST_F(JsonStreamParserTest, EmptySingleQuotedString) {
288  StringPiece str = "''";
289  for (int i = 0; i <= str.length(); ++i) {
290  ow_.RenderString("", "");
291  DoTest(str, i);
292  }
293 }
294 
295 TEST_F(JsonStreamParserTest, SimpleDoubleQuotedString) {
296  StringPiece str = "\"Some String\"";
297  for (int i = 0; i <= str.length(); ++i) {
298  ow_.RenderString("", "Some String");
299  DoTest(str, i);
300  }
301 }
302 
303 TEST_F(JsonStreamParserTest, SimpleSingleQuotedString) {
304  StringPiece str = "'Another String'";
305  for (int i = 0; i <= str.length(); ++i) {
306  ow_.RenderString("", "Another String");
307  DoTest(str, i);
308  }
309 }
310 
311 // - string key, unquoted key, numeric key
312 TEST_F(JsonStreamParserTest, ObjectKeyTypes) {
313  StringPiece str =
314  "{'s': true, \"d\": false, key: null, snake_key: [], camelKey: {}}";
315  for (int i = 0; i <= str.length(); ++i) {
316  ow_.StartObject("")
317  ->RenderBool("s", true)
318  ->RenderBool("d", false)
319  ->RenderNull("key")
320  ->StartList("snake_key")
321  ->EndList()
322  ->StartObject("camelKey")
323  ->EndObject()
324  ->EndObject();
325  DoTest(str, i);
326  }
327 }
328 
329 // - array containing primitive values (true, false, null, num, string)
330 TEST_F(JsonStreamParserTest, ArrayPrimitiveValues) {
331  StringPiece str = "[true, false, null, 'one', \"two\"]";
332  for (int i = 0; i <= str.length(); ++i) {
333  ow_.StartList("")
334  ->RenderBool("", true)
335  ->RenderBool("", false)
336  ->RenderNull("")
337  ->RenderString("", "one")
338  ->RenderString("", "two")
339  ->EndList();
340  DoTest(str, i);
341  }
342 }
343 
344 // - array containing array, object
345 TEST_F(JsonStreamParserTest, ArrayComplexValues) {
346  StringPiece str =
347  "[[22, -127, 45.3, -1056.4, 11779497823553162765], {'key': true}]";
348  for (int i = 0; i <= str.length(); ++i) {
349  ow_.StartList("")
350  ->StartList("")
351  ->RenderUint64("", 22)
352  ->RenderInt64("", -127)
353  ->RenderDouble("", 45.3)
354  ->RenderDouble("", -1056.4)
355  ->RenderUint64("", 11779497823553162765ULL)
356  ->EndList()
357  ->StartObject("")
358  ->RenderBool("key", true)
359  ->EndObject()
360  ->EndList();
361  DoTest(str, i);
362  }
363 }
364 
365 
366 // - object containing array, object, value (true, false, null, num, string)
367 TEST_F(JsonStreamParserTest, ObjectValues) {
368  StringPiece str =
369  "{t: true, f: false, n: null, s: 'a string', d: \"another string\", pi: "
370  "22, ni: -127, pd: 45.3, nd: -1056.4, pl: 11779497823553162765, l: [[]], "
371  "o: {'key': true}}";
372  for (int i = 0; i <= str.length(); ++i) {
373  ow_.StartObject("")
374  ->RenderBool("t", true)
375  ->RenderBool("f", false)
376  ->RenderNull("n")
377  ->RenderString("s", "a string")
378  ->RenderString("d", "another string")
379  ->RenderUint64("pi", 22)
380  ->RenderInt64("ni", -127)
381  ->RenderDouble("pd", 45.3)
382  ->RenderDouble("nd", -1056.4)
383  ->RenderUint64("pl", 11779497823553162765ULL)
384  ->StartList("l")
385  ->StartList("")
386  ->EndList()
387  ->EndList()
388  ->StartObject("o")
389  ->RenderBool("key", true)
390  ->EndObject()
391  ->EndObject();
392  DoTest(str, i);
393  }
394 }
395 
396 
397 TEST_F(JsonStreamParserTest, RejectNonUtf8WhenNotCoerced) {
398  StringPiece json = "{\"address\":\xFF\"חרושת 23, רעננה, ישראל\"}";
399  for (int i = 0; i <= json.length(); ++i) {
400  DoErrorTest(json, i, "Encountered non UTF-8 code points.");
401  }
402  json = "{\"address\": \"חרושת 23,\xFFרעננה, ישראל\"}";
403  for (int i = 0; i <= json.length(); ++i) {
404  DoErrorTest(json, i, "Encountered non UTF-8 code points.");
405  }
406  DoErrorTest("\xFF{}", 0, "Encountered non UTF-8 code points.");
407 }
408 
409 // - unicode handling in strings
410 TEST_F(JsonStreamParserTest, UnicodeEscaping) {
411  StringPiece str = "[\"\\u0639\\u0631\\u0628\\u0649\"]";
412  for (int i = 0; i <= str.length(); ++i) {
413  ow_.StartList("")
414  ->RenderString("", "\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x89")
415  ->EndList();
416  DoTest(str, i);
417  }
418 }
419 
420 // - unicode UTF-16 surrogate pair handling in strings
421 TEST_F(JsonStreamParserTest, UnicodeSurrogatePairEscaping) {
422  StringPiece str =
423  "[\"\\u0bee\\ud800\\uddf1\\uD80C\\uDDA4\\uD83d\\udC1D\\uD83C\\uDF6F\"]";
424  for (int i = 0; i <= str.length(); ++i) {
425  ow_.StartList("")
426  ->RenderString("",
427  "\xE0\xAF\xAE\xF0\x90\x87\xB1\xF0\x93\x86\xA4\xF0"
428  "\x9F\x90\x9D\xF0\x9F\x8D\xAF")
429  ->EndList();
430  DoTest(str, i);
431  }
432 }
433 
434 
435 TEST_F(JsonStreamParserTest, UnicodeEscapingInvalidCodePointWhenNotCoerced) {
436  // A low surrogate alone.
437  StringPiece str = "[\"\\ude36\"]";
438  for (int i = 0; i <= str.length(); ++i) {
439  DoErrorTest(str, i, "Invalid unicode code point.");
440  }
441 }
442 
443 TEST_F(JsonStreamParserTest, UnicodeEscapingMissingLowSurrogateWhenNotCoerced) {
444  // A high surrogate alone.
445  StringPiece str = "[\"\\ud83d\"]";
446  for (int i = 0; i <= str.length(); ++i) {
447  DoErrorTest(str, i, "Missing low surrogate.");
448  }
449  // A high surrogate with some trailing characters.
450  str = "[\"\\ud83d|ude36\"]";
451  for (int i = 0; i <= str.length(); ++i) {
452  DoErrorTest(str, i, "Missing low surrogate.");
453  }
454  // A high surrogate with half a low surrogate.
455  str = "[\"\\ud83d\\ude--\"]";
456  for (int i = 0; i <= str.length(); ++i) {
457  DoErrorTest(str, i, "Invalid escape sequence.");
458  }
459  // Two high surrogates.
460  str = "[\"\\ud83d\\ud83d\"]";
461  for (int i = 0; i <= str.length(); ++i) {
462  DoErrorTest(str, i, "Invalid low surrogate.");
463  }
464 }
465 
466 // - ascii escaping (\b, \f, \n, \r, \t, \v)
467 TEST_F(JsonStreamParserTest, AsciiEscaping) {
468  StringPiece str =
469  "[\"\\b\", \"\\ning\", \"test\\f\", \"\\r\\t\", \"test\\\\\\ving\"]";
470  for (int i = 0; i <= str.length(); ++i) {
471  ow_.StartList("")
472  ->RenderString("", "\b")
473  ->RenderString("", "\ning")
474  ->RenderString("", "test\f")
475  ->RenderString("", "\r\t")
476  ->RenderString("", "test\\\ving")
477  ->EndList();
478  DoTest(str, i);
479  }
480 }
481 
482 // - trailing commas, we support a single trailing comma but no internal commas.
483 TEST_F(JsonStreamParserTest, TrailingCommas) {
484  StringPiece str = "[['a',true,], {b: null,},]";
485  for (int i = 0; i <= str.length(); ++i) {
486  ow_.StartList("")
487  ->StartList("")
488  ->RenderString("", "a")
489  ->RenderBool("", true)
490  ->EndList()
491  ->StartObject("")
492  ->RenderNull("b")
493  ->EndObject()
494  ->EndList();
495  DoTest(str, i);
496  }
497 }
498 
499 // Negative tests
500 
501 // illegal literals
502 TEST_F(JsonStreamParserTest, ExtraTextAfterTrue) {
503  StringPiece str = "truee";
504  for (int i = 0; i <= str.length(); ++i) {
505  ow_.RenderBool("", true);
506  DoErrorTest(str, i, "Parsing terminated before end of input.");
507  }
508 }
509 
510 TEST_F(JsonStreamParserTest, InvalidNumberDashOnly) {
511  StringPiece str = "-";
512  for (int i = 0; i <= str.length(); ++i) {
513  DoErrorTest(str, i, "Unable to parse number.");
514  }
515 }
516 
517 TEST_F(JsonStreamParserTest, InvalidNumberDashName) {
518  StringPiece str = "-foo";
519  for (int i = 0; i <= str.length(); ++i) {
520  DoErrorTest(str, i, "Unable to parse number.");
521  }
522 }
523 
524 TEST_F(JsonStreamParserTest, InvalidLiteralInArray) {
525  StringPiece str = "[nule]";
526  for (int i = 0; i <= str.length(); ++i) {
527  ow_.StartList("");
528  DoErrorTest(str, i, "Unexpected token.");
529  }
530 }
531 
532 TEST_F(JsonStreamParserTest, InvalidLiteralInObject) {
533  StringPiece str = "{123false}";
534  for (int i = 0; i <= str.length(); ++i) {
535  ow_.StartObject("");
536  DoErrorTest(str, i, "Expected an object key or }.");
537  }
538 }
539 
540 // mismatched quotes failure on strings
541 TEST_F(JsonStreamParserTest, MismatchedSingleQuotedLiteral) {
542  StringPiece str = "'Some str\"";
543  for (int i = 0; i <= str.length(); ++i) {
544  DoErrorTest(str, i, "Closing quote expected in string.");
545  }
546 }
547 
548 TEST_F(JsonStreamParserTest, MismatchedDoubleQuotedLiteral) {
549  StringPiece str = "\"Another string that ends poorly!'";
550  for (int i = 0; i <= str.length(); ++i) {
551  DoErrorTest(str, i, "Closing quote expected in string.");
552  }
553 }
554 
555 // unterminated strings
556 TEST_F(JsonStreamParserTest, UnterminatedLiteralString) {
557  StringPiece str = "\"Forgot the rest of i";
558  for (int i = 0; i <= str.length(); ++i) {
559  DoErrorTest(str, i, "Closing quote expected in string.");
560  }
561 }
562 
563 TEST_F(JsonStreamParserTest, UnterminatedStringEscape) {
564  StringPiece str = "\"Forgot the rest of \\";
565  for (int i = 0; i <= str.length(); ++i) {
566  DoErrorTest(str, i, "Closing quote expected in string.");
567  }
568 }
569 
570 TEST_F(JsonStreamParserTest, UnterminatedStringInArray) {
571  StringPiece str = "[\"Forgot to close the string]";
572  for (int i = 0; i <= str.length(); ++i) {
573  ow_.StartList("");
574  DoErrorTest(str, i, "Closing quote expected in string.");
575  }
576 }
577 
578 TEST_F(JsonStreamParserTest, UnterminatedStringInObject) {
579  StringPiece str = "{f: \"Forgot to close the string}";
580  for (int i = 0; i <= str.length(); ++i) {
581  ow_.StartObject("");
582  DoErrorTest(str, i, "Closing quote expected in string.");
583  }
584 }
585 
586 TEST_F(JsonStreamParserTest, UnterminatedObject) {
587  StringPiece str = "{";
588  for (int i = 0; i <= str.length(); ++i) {
589  ow_.StartObject("");
590  DoErrorTest(str, i, "Unexpected end of string.");
591  }
592 }
593 
594 
595 // mismatched object and array closing
596 TEST_F(JsonStreamParserTest, MismatchedCloseObject) {
597  StringPiece str = "{'key': true]";
598  for (int i = 0; i <= str.length(); ++i) {
599  ow_.StartObject("")->RenderBool("key", true);
600  DoErrorTest(str, i, "Expected , or } after key:value pair.");
601  }
602 }
603 
604 TEST_F(JsonStreamParserTest, MismatchedCloseArray) {
605  StringPiece str = "[true, null}";
606  for (int i = 0; i <= str.length(); ++i) {
607  ow_.StartList("")->RenderBool("", true)->RenderNull("");
608  DoErrorTest(str, i, "Expected , or ] after array value.");
609  }
610 }
611 
612 // Invalid object keys.
613 TEST_F(JsonStreamParserTest, InvalidNumericObjectKey) {
614  StringPiece str = "{42: true}";
615  for (int i = 0; i <= str.length(); ++i) {
616  ow_.StartObject("");
617  DoErrorTest(str, i, "Expected an object key or }.");
618  }
619 }
620 
621 TEST_F(JsonStreamParserTest, InvalidLiteralObjectInObject) {
622  StringPiece str = "{{bob: true}}";
623  for (int i = 0; i <= str.length(); ++i) {
624  ow_.StartObject("");
625  DoErrorTest(str, i, "Expected an object key or }.");
626  }
627 }
628 
629 TEST_F(JsonStreamParserTest, InvalidLiteralArrayInObject) {
630  StringPiece str = "{[null]}";
631  for (int i = 0; i <= str.length(); ++i) {
632  ow_.StartObject("");
633  DoErrorTest(str, i, "Expected an object key or }.");
634  }
635 }
636 
637 TEST_F(JsonStreamParserTest, InvalidLiteralValueInObject) {
638  StringPiece str = "{false}";
639  for (int i = 0; i <= str.length(); ++i) {
640  ow_.StartObject("");
641  DoErrorTest(str, i, "Expected an object key or }.");
642  }
643 }
644 
645 TEST_F(JsonStreamParserTest, MissingColonAfterStringInObject) {
646  StringPiece str = "{\"key\"}";
647  for (int i = 0; i <= str.length(); ++i) {
648  ow_.StartObject("");
649  DoErrorTest(str, i, "Expected : between key:value pair.");
650  }
651 }
652 
653 TEST_F(JsonStreamParserTest, MissingColonAfterKeyInObject) {
654  StringPiece str = "{key}";
655  for (int i = 0; i <= str.length(); ++i) {
656  ow_.StartObject("");
657  DoErrorTest(str, i, "Expected : between key:value pair.");
658  }
659 }
660 
661 TEST_F(JsonStreamParserTest, EndOfTextAfterKeyInObject) {
662  StringPiece str = "{key";
663  for (int i = 0; i <= str.length(); ++i) {
664  ow_.StartObject("");
665  DoErrorTest(str, i, "Unexpected end of string.");
666  }
667 }
668 
669 TEST_F(JsonStreamParserTest, MissingValueAfterColonInObject) {
670  StringPiece str = "{key:}";
671  for (int i = 0; i <= str.length(); ++i) {
672  ow_.StartObject("");
673  DoErrorTest(str, i, "Unexpected token.");
674  }
675 }
676 
677 TEST_F(JsonStreamParserTest, MissingCommaBetweenObjectEntries) {
678  StringPiece str = "{key:20 'hello': true}";
679  for (int i = 0; i <= str.length(); ++i) {
680  ow_.StartObject("")->RenderUint64("key", 20);
681  DoErrorTest(str, i, "Expected , or } after key:value pair.");
682  }
683 }
684 
685 TEST_F(JsonStreamParserTest, InvalidLiteralAsObjectKey) {
686  StringPiece str = "{false: 20}";
687  for (int i = 0; i <= str.length(); ++i) {
688  ow_.StartObject("");
689  DoErrorTest(str, i, "Expected an object key or }.");
690  }
691 }
692 
693 TEST_F(JsonStreamParserTest, ExtraCharactersAfterObject) {
694  StringPiece str = "{}}";
695  for (int i = 0; i <= str.length(); ++i) {
696  ow_.StartObject("")->EndObject();
697  DoErrorTest(str, i, "Parsing terminated before end of input.");
698  }
699 }
700 
701 TEST_F(JsonStreamParserTest, PositiveNumberTooBigIsDouble) {
702  StringPiece str = "18446744073709551616"; // 2^64
703  for (int i = 0; i <= str.length(); ++i) {
704  ow_.RenderDouble("", 18446744073709552000.0);
705  DoTest(str, i);
706  }
707 }
708 
709 TEST_F(JsonStreamParserTest, NegativeNumberTooBigIsDouble) {
710  StringPiece str = "-18446744073709551616";
711  for (int i = 0; i <= str.length(); ++i) {
712  ow_.RenderDouble("", -18446744073709551616.0);
713  DoTest(str, i);
714  }
715 }
716 
717 TEST_F(JsonStreamParserTest, DoubleTooBig) {
718  StringPiece str = "[1.89769e+308]";
719  for (int i = 0; i <= str.length(); ++i) {
720  ow_.StartList("");
721  DoErrorTest(str, i, "Number exceeds the range of double.");
722  }
723  str = "[-1.89769e+308]";
724  for (int i = 0; i <= str.length(); ++i) {
725  ow_.StartList("");
726  DoErrorTest(str, i, "Number exceeds the range of double.");
727  }
728 }
729 
730 
731 // invalid bare backslash.
732 TEST_F(JsonStreamParserTest, UnfinishedEscape) {
733  StringPiece str = "\"\\";
734  for (int i = 0; i <= str.length(); ++i) {
735  DoErrorTest(str, i, "Closing quote expected in string.");
736  }
737 }
738 
739 // invalid bare backslash u.
740 TEST_F(JsonStreamParserTest, UnfinishedUnicodeEscape) {
741  StringPiece str = "\"\\u";
742  for (int i = 0; i <= str.length(); ++i) {
743  DoErrorTest(str, i, "Illegal hex string.");
744  }
745 }
746 
747 // invalid unicode sequence.
748 TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) {
749  StringPiece str = "\"\\u12";
750  for (int i = 0; i <= str.length(); ++i) {
751  DoErrorTest(str, i, "Illegal hex string.");
752  }
753 }
754 
755 // invalid unicode sequence (valid in modern EcmaScript but not in JSON).
756 TEST_F(JsonStreamParserTest, BracketedUnicodeEscape) {
757  StringPiece str = "\"\\u{1f36f}\"";
758  for (int i = 0; i <= str.length(); ++i) {
759  DoErrorTest(str, i, "Invalid escape sequence.");
760  }
761 }
762 
763 
764 TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) {
765  StringPiece str = "\"\\u12$4hello";
766  for (int i = 0; i <= str.length(); ++i) {
767  DoErrorTest(str, i, "Invalid escape sequence.");
768  }
769 }
770 
771 // invalid unicode sequence in low half surrogate: g is not a hex digit.
772 TEST_F(JsonStreamParserTest, UnicodeEscapeLowHalfSurrogateInvalidCharacters) {
773  StringPiece str = "\"\\ud800\\udcfg\"";
774  for (int i = 0; i <= str.length(); ++i) {
775  DoErrorTest(str, i, "Invalid escape sequence.");
776  }
777 }
778 
779 // Extra commas with an object or array.
780 TEST_F(JsonStreamParserTest, ExtraCommaInObject) {
781  StringPiece str = "{'k1': true,,'k2': false}";
782  for (int i = 0; i <= str.length(); ++i) {
783  ow_.StartObject("")->RenderBool("k1", true);
784  DoErrorTest(str, i, "Expected an object key or }.");
785  }
786 }
787 
788 TEST_F(JsonStreamParserTest, ExtraCommaInArray) {
789  StringPiece str = "[true,,false}";
790  for (int i = 0; i <= str.length(); ++i) {
791  ow_.StartList("")->RenderBool("", true);
792  DoErrorTest(str, i, "Unexpected token.");
793  }
794 }
795 
796 // Extra text beyond end of value.
797 TEST_F(JsonStreamParserTest, ExtraTextAfterLiteral) {
798  StringPiece str = "'hello', 'world'";
799  for (int i = 0; i <= str.length(); ++i) {
800  ow_.RenderString("", "hello");
801  DoErrorTest(str, i, "Parsing terminated before end of input.");
802  }
803 }
804 
805 TEST_F(JsonStreamParserTest, ExtraTextAfterObject) {
806  StringPiece str = "{'key': true} 'oops'";
807  for (int i = 0; i <= str.length(); ++i) {
808  ow_.StartObject("")->RenderBool("key", true)->EndObject();
809  DoErrorTest(str, i, "Parsing terminated before end of input.");
810  }
811 }
812 
813 TEST_F(JsonStreamParserTest, ExtraTextAfterArray) {
814  StringPiece str = "[null] 'oops'";
815  for (int i = 0; i <= str.length(); ++i) {
816  ow_.StartList("")->RenderNull("")->EndList();
817  DoErrorTest(str, i, "Parsing terminated before end of input.");
818  }
819 }
820 
821 // Random unknown text in the value.
822 TEST_F(JsonStreamParserTest, UnknownCharactersAsValue) {
823  StringPiece str = "*&#25";
824  for (int i = 0; i <= str.length(); ++i) {
825  DoErrorTest(str, i, "Expected a value.");
826  }
827 }
828 
829 TEST_F(JsonStreamParserTest, UnknownCharactersInArray) {
830  StringPiece str = "[*&#25]";
831  for (int i = 0; i <= str.length(); ++i) {
832  ow_.StartList("");
833  DoErrorTest(str, i, "Expected a value or ] within an array.");
834  }
835 }
836 
837 TEST_F(JsonStreamParserTest, UnknownCharactersInObject) {
838  StringPiece str = "{'key': *&#25}";
839  for (int i = 0; i <= str.length(); ++i) {
840  ow_.StartObject("");
841  DoErrorTest(str, i, "Expected a value.");
842  }
843 }
844 
845 TEST_F(JsonStreamParserTest, DeepNestJsonNotExceedLimit) {
846  int count = 99;
848  for (int i = 0; i < count; ++i) {
849  StrAppend(&str, "{'a':");
850  }
851  StrAppend(&str, "{'nest64':'v1', 'nest64': false, 'nest64': ['v2']}");
852  for (int i = 0; i < count; ++i) {
853  StrAppend(&str, "}");
854  }
855  ow_.StartObject("");
856  for (int i = 0; i < count; ++i) {
857  ow_.StartObject("a");
858  }
859  ow_.RenderString("nest64", "v1")
860  ->RenderBool("nest64", false)
861  ->StartList("nest64")
862  ->RenderString("", "v2")
863  ->EndList();
864  for (int i = 0; i < count; ++i) {
865  ow_.EndObject();
866  }
867  ow_.EndObject();
868  DoTest(str, 0);
869 }
870 
871 TEST_F(JsonStreamParserTest, DeepNestJsonExceedLimit) {
872  int count = 98;
874  for (int i = 0; i < count; ++i) {
875  StrAppend(&str, "{'a':");
876  }
877  // Supports trailing commas.
878  StrAppend(&str,
879  "{'nest11' : [{'nest12' : null,},],"
880  "'nest21' : {'nest22' : {'nest23' : false}}}");
881  for (int i = 0; i < count; ++i) {
882  StrAppend(&str, "}");
883  }
884  DoErrorTest(str, 0,
885  "Message too deep. Max recursion depth reached for key 'nest22'");
886 }
887 
888 } // namespace converter
889 } // namespace util
890 } // namespace protobuf
891 } // namespace google
google::protobuf::util::converter::JsonStreamParserTest::RunTest
util::Status RunTest(StringPiece json, int split, bool coerce_utf8=false, bool allow_empty_null=false, bool loose_float_number_conversion=false)
Definition: json_stream_parser_test.cc:92
INFO
const int INFO
Definition: log_severity.h:59
google::protobuf::util::converter::TEST_F
TEST_F(JsonObjectWriterTest, EmptyRootObject)
Definition: json_objectwriter_test.cc:66
DoTest
void DoTest(const ConformanceRequest &request, ConformanceResponse *response)
Definition: conformance_cpp.cc:125
google::protobuf::util::Status::code
error::Code code() const
Definition: status.h:93
google::protobuf::StringPiece::length
stringpiece_ssize_type length() const
Definition: stringpiece.h:249
google::protobuf::util::converter::JsonStreamParserTest::JsonStreamParserTest
JsonStreamParserTest()
Definition: json_stream_parser_test.cc:89
gtest.h
json_stream_parser.h
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
google::protobuf::util::Status::error_message
StringPiece error_message() const
Definition: status.h:96
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::util::converter::JsonStreamParserTest::DoErrorTest
void DoErrorTest(StringPiece json, int split, StringPiece error_prefix, bool coerce_utf8=false, bool allow_empty_null=false)
Definition: json_stream_parser_test.cc:138
google::protobuf::util::converter::ExpectingObjectWriter
Definition: expecting_objectwriter.h:91
google::protobuf::StringPiece::substr
StringPiece substr(size_type pos, size_type n=npos) const
Definition: stringpiece.cc:261
error
Definition: cJSON.c:88
testing::Test
Definition: gtest.h:415
google::protobuf::util::converter::MockObjectWriter
Definition: expecting_objectwriter.h:70
expecting_objectwriter.h
strutil.h
google::protobuf::util::converter::JsonStreamParserTest::~JsonStreamParserTest
virtual ~JsonStreamParserTest()
Definition: json_stream_parser_test.cc:90
google::protobuf::StringPiece
Definition: stringpiece.h:180
update_failure_list.str
str
Definition: update_failure_list.py:41
google::protobuf::util::converter::JsonStreamParser
Definition: json_stream_parser.h:70
time.h
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
EXPECT_OK
#define EXPECT_OK(value)
Definition: status.h:119
google::protobuf::WARNING
static const LogLevel WARNING
Definition: protobuf/src/google/protobuf/testing/googletest.h:71
ULL
#define ULL(x)
Definition: coded_stream_unittest.cc:57
google::protobuf::util::error::INVALID_ARGUMENT
@ INVALID_ARGUMENT
Definition: status.h:50
google::protobuf::util::converter::JsonStreamParserTest::ow_
ExpectingObjectWriter ow_
Definition: json_stream_parser_test.cc:155
aditof::Status
Status
Status of any operation that the TOF sdk performs.
Definition: status_definitions.h:48
google::protobuf::util::converter::JsonStreamParserTest::mock_
MockObjectWriter mock_
Definition: json_stream_parser_test.cc:154
LL
#define LL(x)
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::util::Status::ok
bool ok() const
Definition: status.h:87
common.h
object_writer.h
google::protobuf::util::converter::JsonStreamParserTest::DoTest
void DoTest(StringPiece json, int split, bool coerce_utf8=false, bool allow_empty_null=false, bool loose_float_number_conversion=false)
Definition: json_stream_parser_test.cc:127
google::protobuf::util::converter::JsonStreamParserTest
Definition: json_stream_parser_test.cc:87
logging.h
google::protobuf::util::Status
Definition: status.h:67
google::protobuf::util::converter::JsonStreamParserTest::in_sequence_
::testing::InSequence in_sequence_
Definition: json_stream_parser_test.cc:152
first
GLint first
Definition: glcorearb.h:2830
benchmarks.python.py_benchmark.parser
parser
Definition: py_benchmark.py:10
count
GLint GLsizei count
Definition: glcorearb.h:2830
status.h
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::StrAppend
void StrAppend(string *result, const AlphaNum &a)
Definition: strutil.cc:1581
zmq::error_prefix
const char error_prefix[]
Definition: plain_common.hpp:20


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55