]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/nlohmann-json/test/src/unit-deserialization.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / nlohmann-json / test / src / unit-deserialization.cpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++ (test suite)
4 | | |__ | | | | | | version 3.10.5
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #include "doctest_compatibility.h"
31
32 #include <nlohmann/json.hpp>
33 using nlohmann::json;
34
35 #include <iostream>
36 #include <sstream>
37 #include <valarray>
38
39 namespace
40 {
41 struct SaxEventLogger : public nlohmann::json_sax<json>
42 {
43 bool null() override
44 {
45 events.emplace_back("null()");
46 return true;
47 }
48
49 bool boolean(bool val) override
50 {
51 events.emplace_back(val ? "boolean(true)" : "boolean(false)");
52 return true;
53 }
54
55 bool number_integer(json::number_integer_t val) override
56 {
57 events.push_back("number_integer(" + std::to_string(val) + ")");
58 return true;
59 }
60
61 bool number_unsigned(json::number_unsigned_t val) override
62 {
63 events.push_back("number_unsigned(" + std::to_string(val) + ")");
64 return true;
65 }
66
67 bool number_float(json::number_float_t /*val*/, const std::string& s) override
68 {
69 events.push_back("number_float(" + s + ")");
70 return true;
71 }
72
73 bool string(std::string& val) override
74 {
75 events.push_back("string(" + val + ")");
76 return true;
77 }
78
79 bool binary(json::binary_t& val) override
80 {
81 std::string binary_contents = "binary(";
82 std::string comma_space;
83 for (auto b : val)
84 {
85 binary_contents.append(comma_space);
86 binary_contents.append(std::to_string(static_cast<int>(b)));
87 comma_space = ", ";
88 }
89 binary_contents.append(")");
90 events.push_back(binary_contents);
91 return true;
92 }
93
94 bool start_object(std::size_t elements) override
95 {
96 if (elements == static_cast<std::size_t>(-1))
97 {
98 events.emplace_back("start_object()");
99 }
100 else
101 {
102 events.push_back("start_object(" + std::to_string(elements) + ")");
103 }
104 return true;
105 }
106
107 bool key(std::string& val) override
108 {
109 events.push_back("key(" + val + ")");
110 return true;
111 }
112
113 bool end_object() override
114 {
115 events.emplace_back("end_object()");
116 return true;
117 }
118
119 bool start_array(std::size_t elements) override
120 {
121 if (elements == static_cast<std::size_t>(-1))
122 {
123 events.emplace_back("start_array()");
124 }
125 else
126 {
127 events.push_back("start_array(" + std::to_string(elements) + ")");
128 }
129 return true;
130 }
131
132 bool end_array() override
133 {
134 events.emplace_back("end_array()");
135 return true;
136 }
137
138 bool parse_error(std::size_t position, const std::string& /*last_token*/, const json::exception& /*ex*/) override
139 {
140 events.push_back("parse_error(" + std::to_string(position) + ")");
141 return false;
142 }
143
144 std::vector<std::string> events {};
145 };
146
147 struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
148 {
149 bool start_object(std::size_t elements) override
150 {
151 if (elements == static_cast<std::size_t>(-1))
152 {
153 events.emplace_back("start_object()");
154 }
155 else
156 {
157 events.push_back("start_object(" + std::to_string(elements) + ")");
158 }
159 return false;
160 }
161 };
162
163 struct SaxEventLoggerExitAfterKey : public SaxEventLogger
164 {
165 bool key(std::string& val) override
166 {
167 events.push_back("key(" + val + ")");
168 return false;
169 }
170 };
171
172 struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
173 {
174 bool start_array(std::size_t elements) override
175 {
176 if (elements == static_cast<std::size_t>(-1))
177 {
178 events.emplace_back("start_array()");
179 }
180 else
181 {
182 events.push_back("start_array(" + std::to_string(elements) + ")");
183 }
184 return false;
185 }
186 };
187 } // namespace
188
189 TEST_CASE("deserialization")
190 {
191 SECTION("successful deserialization")
192 {
193 SECTION("stream")
194 {
195 std::stringstream ss1;
196 std::stringstream ss2;
197 std::stringstream ss3;
198 ss1 << R"(["foo",1,2,3,false,{"one":1}])";
199 ss2 << R"(["foo",1,2,3,false,{"one":1}])";
200 ss3 << R"(["foo",1,2,3,false,{"one":1}])";
201 json j = json::parse(ss1);
202 CHECK(json::accept(ss2));
203 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
204
205 SaxEventLogger l;
206 CHECK(json::sax_parse(ss3, &l));
207 CHECK(l.events.size() == 11);
208 CHECK(l.events == std::vector<std::string>(
209 {
210 "start_array()", "string(foo)", "number_unsigned(1)",
211 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
212 "start_object()", "key(one)", "number_unsigned(1)",
213 "end_object()", "end_array()"
214 }));
215 }
216
217 SECTION("string literal")
218 {
219 const auto* s = R"(["foo",1,2,3,false,{"one":1}])";
220 json j = json::parse(s);
221 CHECK(json::accept(s));
222 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
223
224 SaxEventLogger l;
225 CHECK(json::sax_parse(s, &l));
226 CHECK(l.events.size() == 11);
227 CHECK(l.events == std::vector<std::string>(
228 {
229 "start_array()", "string(foo)", "number_unsigned(1)",
230 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
231 "start_object()", "key(one)", "number_unsigned(1)",
232 "end_object()", "end_array()"
233 }));
234 }
235
236 SECTION("string_t")
237 {
238 json::string_t s = R"(["foo",1,2,3,false,{"one":1}])";
239 json j = json::parse(s);
240 CHECK(json::accept(s));
241 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
242
243 SaxEventLogger l;
244 CHECK(json::sax_parse(s, &l));
245 CHECK(l.events.size() == 11);
246 CHECK(l.events == std::vector<std::string>(
247 {
248 "start_array()", "string(foo)", "number_unsigned(1)",
249 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
250 "start_object()", "key(one)", "number_unsigned(1)",
251 "end_object()", "end_array()"
252 }));
253 }
254
255 SECTION("operator<<")
256 {
257 std::stringstream ss;
258 ss << R"(["foo",1,2,3,false,{"one":1}])";
259 json j;
260 j << ss;
261 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
262 }
263
264 SECTION("operator>>")
265 {
266 std::stringstream ss;
267 ss << R"(["foo",1,2,3,false,{"one":1}])";
268 json j;
269 ss >> j;
270 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
271 }
272
273 SECTION("user-defined string literal")
274 {
275 CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
276 }
277 }
278
279 SECTION("unsuccessful deserialization")
280 {
281 SECTION("stream")
282 {
283 std::stringstream ss1;
284 std::stringstream ss2;
285 std::stringstream ss3;
286 std::stringstream ss4;
287 std::stringstream ss5;
288 ss1 << R"(["foo",1,2,3,false,{"one":1})";
289 ss2 << R"(["foo",1,2,3,false,{"one":1})";
290 ss3 << R"(["foo",1,2,3,false,{"one":1})";
291 ss4 << R"(["foo",1,2,3,false,{"one":1})";
292 ss5 << R"(["foo",1,2,3,false,{"one":1})";
293
294 json _;
295 CHECK_THROWS_AS(_ = json::parse(ss1), json::parse_error&);
296 CHECK_THROWS_WITH(_ = json::parse(ss2),
297 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
298 CHECK(!json::accept(ss3));
299
300 json j_error;
301 CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false));
302 CHECK(j_error.is_discarded());
303
304 SaxEventLogger l;
305 CHECK(!json::sax_parse(ss5, &l));
306 CHECK(l.events.size() == 11);
307 CHECK(l.events == std::vector<std::string>(
308 {
309 "start_array()", "string(foo)", "number_unsigned(1)",
310 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
311 "start_object()", "key(one)", "number_unsigned(1)",
312 "end_object()", "parse_error(29)"
313 }));
314 }
315
316 SECTION("string")
317 {
318 json::string_t s = R"(["foo",1,2,3,false,{"one":1})";
319 json _;
320 CHECK_THROWS_AS(_ = json::parse(s), json::parse_error&);
321 CHECK_THROWS_WITH(_ = json::parse(s),
322 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
323 CHECK(!json::accept(s));
324
325 json j_error;
326 CHECK_NOTHROW(j_error = json::parse(s, nullptr, false));
327 CHECK(j_error.is_discarded());
328
329 SaxEventLogger l;
330 CHECK(!json::sax_parse(s, &l));
331 CHECK(l.events.size() == 11);
332 CHECK(l.events == std::vector<std::string>(
333 {
334 "start_array()", "string(foo)", "number_unsigned(1)",
335 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
336 "start_object()", "key(one)", "number_unsigned(1)",
337 "end_object()", "parse_error(29)"
338 }));
339 }
340
341 SECTION("operator<<")
342 {
343 std::stringstream ss1;
344 std::stringstream ss2;
345 ss1 << R"(["foo",1,2,3,false,{"one":1})";
346 ss2 << R"(["foo",1,2,3,false,{"one":1})";
347 json j;
348 CHECK_THROWS_AS(j << ss1, json::parse_error&);
349 CHECK_THROWS_WITH(j << ss2,
350 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
351 }
352
353 SECTION("operator>>")
354 {
355 std::stringstream ss1;
356 std::stringstream ss2;
357 ss1 << R"(["foo",1,2,3,false,{"one":1})";
358 ss2 << R"(["foo",1,2,3,false,{"one":1})";
359 json j;
360 CHECK_THROWS_AS(ss1 >> j, json::parse_error&);
361 CHECK_THROWS_WITH(ss2 >> j,
362 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
363 }
364
365 SECTION("user-defined string literal")
366 {
367 CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&);
368 CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
369 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
370 }
371 }
372
373 SECTION("contiguous containers")
374 {
375 SECTION("directly")
376 {
377 SECTION("from std::vector")
378 {
379 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
380 CHECK(json::parse(v) == json(true));
381 CHECK(json::accept(v));
382
383 SaxEventLogger l;
384 CHECK(json::sax_parse(v, &l));
385 CHECK(l.events.size() == 1);
386 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
387 }
388
389 SECTION("from std::array")
390 {
391 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
392 CHECK(json::parse(v) == json(true));
393 CHECK(json::accept(v));
394
395 SaxEventLogger l;
396 CHECK(json::sax_parse(v, &l));
397 CHECK(l.events.size() == 1);
398 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
399 }
400
401 SECTION("from array")
402 {
403 uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
404 CHECK(json::parse(v) == json(true));
405 CHECK(json::accept(v));
406
407 SaxEventLogger l;
408 CHECK(json::sax_parse(v, &l));
409 CHECK(l.events.size() == 1);
410 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
411 }
412
413 SECTION("from chars")
414 {
415 auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)
416 v[0] = 't';
417 v[1] = 'r';
418 v[2] = 'u';
419 v[3] = 'e';
420 v[4] = '\0';
421 CHECK(json::parse(v) == json(true));
422 CHECK(json::accept(v));
423
424 SaxEventLogger l;
425 CHECK(json::sax_parse(v, &l));
426 CHECK(l.events.size() == 1);
427 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
428
429 delete[] v; // NOLINT(cppcoreguidelines-owning-memory)
430 }
431
432 SECTION("from std::string")
433 {
434 std::string v = {'t', 'r', 'u', 'e'};
435 CHECK(json::parse(v) == json(true));
436 CHECK(json::accept(v));
437
438 SaxEventLogger l;
439 CHECK(json::sax_parse(v, &l));
440 CHECK(l.events.size() == 1);
441 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
442 }
443
444 SECTION("from std::initializer_list")
445 {
446 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
447 CHECK(json::parse(v) == json(true));
448 CHECK(json::accept(v));
449
450 SaxEventLogger l;
451 CHECK(json::sax_parse(v, &l));
452 CHECK(l.events.size() == 1);
453 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
454 }
455
456 SECTION("empty container")
457 {
458 std::vector<uint8_t> v;
459 json _;
460 CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&);
461 CHECK(!json::accept(v));
462
463 SaxEventLogger l;
464 CHECK(!json::sax_parse(v, &l));
465 CHECK(l.events.size() == 1);
466 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
467 }
468 }
469
470 SECTION("via iterator range")
471 {
472 SECTION("from std::vector")
473 {
474 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
475 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
476 CHECK(json::accept(std::begin(v), std::end(v)));
477
478 SaxEventLogger l;
479 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
480 CHECK(l.events.size() == 1);
481 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
482
483 }
484
485 SECTION("from std::array")
486 {
487 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
488 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
489 CHECK(json::accept(std::begin(v), std::end(v)));
490
491 SaxEventLogger l;
492 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
493 CHECK(l.events.size() == 1);
494 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
495 }
496
497 SECTION("from array")
498 {
499 uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
500 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
501 CHECK(json::accept(std::begin(v), std::end(v)));
502
503 SaxEventLogger l;
504 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
505 CHECK(l.events.size() == 1);
506 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
507 }
508
509 SECTION("from std::string")
510 {
511 std::string v = {'t', 'r', 'u', 'e'};
512 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
513 CHECK(json::accept(std::begin(v), std::end(v)));
514
515 SaxEventLogger l;
516 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
517 CHECK(l.events.size() == 1);
518 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
519 }
520
521 SECTION("from std::initializer_list")
522 {
523 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
524 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
525 CHECK(json::accept(std::begin(v), std::end(v)));
526
527 SaxEventLogger l;
528 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
529 CHECK(l.events.size() == 1);
530 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
531 }
532
533 SECTION("from std::valarray")
534 {
535 std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
536 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
537 CHECK(json::accept(std::begin(v), std::end(v)));
538
539 SaxEventLogger l;
540 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
541 CHECK(l.events.size() == 1);
542 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
543 }
544
545 SECTION("with empty range")
546 {
547 std::vector<uint8_t> v;
548 json _;
549 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
550 CHECK(!json::accept(std::begin(v), std::end(v)));
551
552 SaxEventLogger l;
553 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
554 CHECK(l.events.size() == 1);
555 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
556 }
557 }
558
559 // these cases are required for 100% line coverage
560 SECTION("error cases")
561 {
562 SECTION("case 1")
563 {
564 std::array<std::uint8_t, 9> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}};
565 json _;
566 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
567 CHECK(!json::accept(std::begin(v), std::end(v)));
568
569 json j_error;
570 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
571 CHECK(j_error.is_discarded());
572
573 SaxEventLogger l;
574 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
575 CHECK(l.events.size() == 1);
576 CHECK(l.events == std::vector<std::string>({"parse_error(10)"}));
577 }
578
579 SECTION("case 2")
580 {
581 std::array<std::uint8_t, 10> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}};
582 json _;
583 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
584 CHECK(!json::accept(std::begin(v), std::end(v)));
585
586 json j_error;
587 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
588 CHECK(j_error.is_discarded());
589
590 SaxEventLogger l;
591 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
592 CHECK(l.events.size() == 1);
593 CHECK(l.events == std::vector<std::string>({"parse_error(11)"}));
594 }
595
596 SECTION("case 3")
597 {
598 std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}};
599 json _;
600 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
601 CHECK(!json::accept(std::begin(v), std::end(v)));
602
603 json j_error;
604 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
605 CHECK(j_error.is_discarded());
606
607 SaxEventLogger l;
608 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
609 CHECK(l.events.size() == 1);
610 CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
611 }
612
613 SECTION("case 4")
614 {
615 std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}};
616 json _;
617 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
618 CHECK(!json::accept(std::begin(v), std::end(v)));
619
620 json j_error;
621 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
622 CHECK(j_error.is_discarded());
623
624 SaxEventLogger l;
625 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
626 CHECK(l.events.size() == 1);
627 CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
628 }
629
630 SECTION("case 5")
631 {
632 std::array<std::uint8_t, 3> v = {{'\"', 0x7F, 0xC1}};
633 json _;
634 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
635 CHECK(!json::accept(std::begin(v), std::end(v)));
636
637 json j_error;
638 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
639 CHECK(j_error.is_discarded());
640
641 SaxEventLogger l;
642 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
643 CHECK(l.events.size() == 1);
644 CHECK(l.events == std::vector<std::string>({"parse_error(3)"}));
645 }
646
647 SECTION("case 6")
648 {
649 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 0x7F}};
650 json _;
651 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
652 CHECK_THROWS_WITH(_ = json::parse(std::begin(v), std::end(v)),
653 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'");
654 CHECK(!json::accept(std::begin(v), std::end(v)));
655
656 json j_error;
657 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
658 CHECK(j_error.is_discarded());
659
660 SaxEventLogger l;
661 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
662 CHECK(l.events.size() == 1);
663 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
664 }
665
666 SECTION("case 7")
667 {
668 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 0xC0}};
669 json _;
670 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
671 CHECK(!json::accept(std::begin(v), std::end(v)));
672
673 json j_error;
674 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
675 CHECK(j_error.is_discarded());
676
677 SaxEventLogger l;
678 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
679 CHECK(l.events.size() == 1);
680 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
681 }
682
683 SECTION("case 8")
684 {
685 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xE0, 0x9F}};
686 json _;
687 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
688 CHECK(!json::accept(std::begin(v), std::end(v)));
689
690 json j_error;
691 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
692 CHECK(j_error.is_discarded());
693
694 SaxEventLogger l;
695 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
696 CHECK(l.events.size() == 1);
697 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
698 }
699
700 SECTION("case 9")
701 {
702 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xEF, 0xC0}};
703 json _;
704 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
705 CHECK(!json::accept(std::begin(v), std::end(v)));
706
707 json j_error;
708 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
709 CHECK(j_error.is_discarded());
710
711 SaxEventLogger l;
712 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
713 CHECK(l.events.size() == 1);
714 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
715 }
716
717 SECTION("case 10")
718 {
719 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xED, 0x7F}};
720 json _;
721 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
722 CHECK(!json::accept(std::begin(v), std::end(v)));
723
724 json j_error;
725 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
726 CHECK(j_error.is_discarded());
727
728 SaxEventLogger l;
729 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
730 CHECK(l.events.size() == 1);
731 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
732 }
733
734 SECTION("case 11")
735 {
736 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 0x8F}};
737 json _;
738 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
739 CHECK(!json::accept(std::begin(v), std::end(v)));
740
741 json j_error;
742 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
743 CHECK(j_error.is_discarded());
744
745 SaxEventLogger l;
746 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
747 CHECK(l.events.size() == 1);
748 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
749 }
750
751 SECTION("case 12")
752 {
753 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 0xC0}};
754 json _;
755 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
756 CHECK(!json::accept(std::begin(v), std::end(v)));
757
758 json j_error;
759 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
760 CHECK(j_error.is_discarded());
761
762 SaxEventLogger l;
763 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
764 CHECK(l.events.size() == 1);
765 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
766 }
767
768 SECTION("case 13")
769 {
770 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 0x7F}};
771 json _;
772 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
773 CHECK(!json::accept(std::begin(v), std::end(v)));
774
775 json j_error;
776 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
777 CHECK(j_error.is_discarded());
778
779 SaxEventLogger l;
780 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
781 CHECK(l.events.size() == 1);
782 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
783 }
784
785 SECTION("case 14")
786 {
787 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 0xC0}};
788 json _;
789 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
790 CHECK(!json::accept(std::begin(v), std::end(v)));
791
792 json j_error;
793 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
794 CHECK(j_error.is_discarded());
795
796 SaxEventLogger l;
797 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
798 CHECK(l.events.size() == 1);
799 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
800 }
801
802 SECTION("case 15")
803 {
804 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF4, 0x7F}};
805 json _;
806 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
807 CHECK(!json::accept(std::begin(v), std::end(v)));
808
809 json j_error;
810 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
811 CHECK(j_error.is_discarded());
812
813 SaxEventLogger l;
814 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
815 CHECK(l.events.size() == 1);
816 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
817 }
818
819 SECTION("case 16")
820 {
821 std::array<std::uint8_t, 6> v = {{'{', '\"', '\"', ':', '1', '1'}};
822 json _;
823 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
824 CHECK(!json::accept(std::begin(v), std::end(v)));
825
826 json j_error;
827 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
828 CHECK(j_error.is_discarded());
829
830 SaxEventLogger l;
831 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
832 CHECK(l.events.size() == 4);
833 CHECK(l.events == std::vector<std::string>(
834 {
835 "start_object()", "key()", "number_unsigned(11)",
836 "parse_error(7)"
837 }));
838 }
839 }
840 }
841
842 SECTION("ignoring byte-order marks")
843 {
844 std::string bom = "\xEF\xBB\xBF";
845
846 SECTION("BOM only")
847 {
848 json _;
849 CHECK_THROWS_AS(_ = json::parse(bom), json::parse_error&);
850 CHECK_THROWS_WITH(_ = json::parse(bom),
851 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
852
853 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom)), json::parse_error&);
854 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom)),
855 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal");
856
857 SaxEventLogger l;
858 CHECK(!json::sax_parse(bom, &l));
859 CHECK(l.events.size() == 1);
860 CHECK(l.events == std::vector<std::string>(
861 {
862 "parse_error(4)"
863 }));
864 }
865
866 SECTION("BOM and content")
867 {
868 CHECK(json::parse(bom + "1") == 1);
869 CHECK(json::parse(std::istringstream(bom + "1")) == 1);
870
871 SaxEventLogger l1;
872 SaxEventLogger l2;
873 CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1));
874 CHECK(json::sax_parse(bom + "1", &l2));
875 CHECK(l1.events.size() == 1);
876 CHECK(l1.events == std::vector<std::string>(
877 {
878 "number_unsigned(1)"
879 }));
880 CHECK(l2.events.size() == 1);
881 CHECK(l2.events == std::vector<std::string>(
882 {
883 "number_unsigned(1)"
884 }));
885 }
886
887 SECTION("2 byte of BOM")
888 {
889 json _;
890 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 2)), json::parse_error&);
891 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 2)),
892 "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'");
893
894 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&);
895 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 2))),
896 "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'");
897
898 SaxEventLogger l1;
899 SaxEventLogger l2;
900 CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
901 CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
902 CHECK(l1.events.size() == 1);
903 CHECK(l1.events == std::vector<std::string>(
904 {
905 "parse_error(3)"
906 }));
907 CHECK(l2.events.size() == 1);
908 CHECK(l2.events == std::vector<std::string>(
909 {
910 "parse_error(3)"
911 }));
912 }
913
914 SECTION("1 byte of BOM")
915 {
916 json _;
917 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 1)), json::parse_error&);
918 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 1)),
919 "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'");
920
921 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&);
922 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 1))),
923 "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'");
924
925 SaxEventLogger l1;
926 SaxEventLogger l2;
927 CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));
928 CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
929 CHECK(l1.events.size() == 1);
930 CHECK(l1.events == std::vector<std::string>(
931 {
932 "parse_error(2)"
933 }));
934 CHECK(l2.events.size() == 1);
935 CHECK(l2.events == std::vector<std::string>(
936 {
937 "parse_error(2)"
938 }));
939 }
940
941 SECTION("variations")
942 {
943 // calculate variations of each byte of the BOM to make sure
944 // that the BOM and only the BOM is skipped
945 for (int i0 = -1; i0 < 2; ++i0)
946 {
947 for (int i1 = -1; i1 < 2; ++i1)
948 {
949 for (int i2 = -1; i2 < 2; ++i2)
950 {
951 // debug output for the variations
952 CAPTURE(i0)
953 CAPTURE(i1)
954 CAPTURE(i2)
955
956 std::string s;
957 s.push_back(static_cast<char>(bom[0] + i0));
958 s.push_back(static_cast<char>(bom[1] + i1));
959 s.push_back(static_cast<char>(bom[2] + i2));
960
961 if (i0 == 0 && i1 == 0 && i2 == 0)
962 {
963 // without any variation, we skip the BOM
964 CHECK(json::parse(s + "null") == json());
965 CHECK(json::parse(std::istringstream(s + "null")) == json());
966
967 SaxEventLogger l;
968 CHECK(json::sax_parse(s + "null", &l));
969 CHECK(l.events.size() == 1);
970 CHECK(l.events == std::vector<std::string>(
971 {
972 "null()"
973 }));
974 }
975 else
976 {
977 // any variation is an error
978 json _;
979 CHECK_THROWS_AS(_ = json::parse(s + "null"), json::parse_error&);
980 CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + "null")), json::parse_error&);
981
982 SaxEventLogger l;
983 CHECK(!json::sax_parse(s + "null", &l));
984 CHECK(l.events.size() == 1);
985
986 if (i0 != 0)
987 {
988 CHECK(l.events == std::vector<std::string>(
989 {
990 "parse_error(1)"
991 }));
992 }
993 else if (i1 != 0)
994 {
995 CHECK(l.events == std::vector<std::string>(
996 {
997 "parse_error(2)"
998 }));
999 }
1000 else
1001 {
1002 CHECK(l.events == std::vector<std::string>(
1003 {
1004 "parse_error(3)"
1005 }));
1006 }
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 SECTION("preserve state after parsing")
1014 {
1015 std::istringstream s(bom + "123 456");
1016 json j;
1017 j << s;
1018 CHECK(j == 123);
1019 j << s;
1020 CHECK(j == 456);
1021 }
1022 }
1023
1024 SECTION("SAX and early abort")
1025 {
1026 std::string s = R"([1, ["string", 43.12], null, {"key1": true, "key2": false}])";
1027
1028 SaxEventLogger default_logger;
1029 SaxEventLoggerExitAfterStartObject exit_after_start_object;
1030 SaxEventLoggerExitAfterKey exit_after_key;
1031 SaxEventLoggerExitAfterStartArray exit_after_start_array;
1032
1033 json::sax_parse(s, &default_logger);
1034 CHECK(default_logger.events.size() == 14);
1035 CHECK(default_logger.events == std::vector<std::string>(
1036 {
1037 "start_array()", "number_unsigned(1)", "start_array()",
1038 "string(string)", "number_float(43.12)", "end_array()", "null()",
1039 "start_object()", "key(key1)", "boolean(true)", "key(key2)",
1040 "boolean(false)", "end_object()", "end_array()"
1041 }));
1042
1043 json::sax_parse(s, &exit_after_start_object);
1044 CHECK(exit_after_start_object.events.size() == 8);
1045 CHECK(exit_after_start_object.events == std::vector<std::string>(
1046 {
1047 "start_array()", "number_unsigned(1)", "start_array()",
1048 "string(string)", "number_float(43.12)", "end_array()", "null()",
1049 "start_object()"
1050 }));
1051
1052 json::sax_parse(s, &exit_after_key);
1053 CHECK(exit_after_key.events.size() == 9);
1054 CHECK(exit_after_key.events == std::vector<std::string>(
1055 {
1056 "start_array()", "number_unsigned(1)", "start_array()",
1057 "string(string)", "number_float(43.12)", "end_array()", "null()",
1058 "start_object()", "key(key1)"
1059 }));
1060
1061 json::sax_parse(s, &exit_after_start_array);
1062 CHECK(exit_after_start_array.events.size() == 1);
1063 CHECK(exit_after_start_array.events == std::vector<std::string>(
1064 {
1065 "start_array()"
1066 }));
1067 }
1068 }
1069
1070 TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
1071 char, unsigned char, signed char,
1072 wchar_t,
1073 char16_t, char32_t,
1074 std::uint8_t, std::int8_t,
1075 std::int16_t, std::uint16_t,
1076 std::int32_t, std::uint32_t)
1077 {
1078 std::vector<T> v = {'t', 'r', 'u', 'e'};
1079 CHECK(json::parse(v) == json(true));
1080 CHECK(json::accept(v));
1081
1082 SaxEventLogger l;
1083 CHECK(json::sax_parse(v, &l));
1084 CHECK(l.events.size() == 1);
1085 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
1086 }
1087
1088 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
1089 char, unsigned char, std::uint8_t)
1090 {
1091 // a star emoji
1092 std::vector<T> v = {'"', static_cast<T>(0xe2u), static_cast<T>(0xadu), static_cast<T>(0x90u), static_cast<T>(0xefu), static_cast<T>(0xb8u), static_cast<T>(0x8fu), '"'};
1093 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1094 CHECK(json::accept(v));
1095
1096 SaxEventLogger l;
1097 CHECK(json::sax_parse(v, &l));
1098 CHECK(l.events.size() == 1);
1099 }
1100
1101 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
1102 char16_t, std::uint16_t)
1103 {
1104 // a star emoji
1105 std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1106 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1107 CHECK(json::accept(v));
1108
1109 SaxEventLogger l;
1110 CHECK(json::sax_parse(v, &l));
1111 CHECK(l.events.size() == 1);
1112 }
1113
1114 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T,
1115 char32_t, std::uint32_t)
1116 {
1117 // a star emoji
1118 std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1119 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1120 CHECK(json::accept(v));
1121
1122 SaxEventLogger l;
1123 CHECK(json::sax_parse(v, &l));
1124 CHECK(l.events.size() == 1);
1125 }