1 //     __ _____ _____ _____
2 //  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3 // |  |  |__   |  |  | | | |  version 3.11.2
4 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5 //
6 // Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
7 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8 // SPDX-License-Identifier: MIT
9 
10 #include "doctest_compatibility.h"
11 
12 #include <nlohmann/json.hpp>
13 using nlohmann::json;
14 #ifdef JSON_TEST_NO_GLOBAL_UDLS
15     using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
16 #endif
17 
18 #include <iostream>
19 #include <iterator>
20 #include <sstream>
21 #include <valarray>
22 
23 namespace
24 {
25 struct SaxEventLogger : public nlohmann::json_sax<json>
26 {
27     bool null() override
28     {
29         events.emplace_back("null()");
30         return true;
31     }
32 
33     bool boolean(bool val) override
34     {
35         events.emplace_back(val ? "boolean(true)" : "boolean(false)");
36         return true;
37     }
38 
39     bool number_integer(json::number_integer_t val) override
40     {
41         events.push_back("number_integer(" + std::to_string(val) + ")");
42         return true;
43     }
44 
45     bool number_unsigned(json::number_unsigned_t val) override
46     {
47         events.push_back("number_unsigned(" + std::to_string(val) + ")");
48         return true;
49     }
50 
51     bool number_float(json::number_float_t /*val*/, const std::string& s) override
52     {
53         events.push_back("number_float(" + s + ")");
54         return true;
55     }
56 
57     bool string(std::string& val) override
58     {
59         events.push_back("string(" + val + ")");
60         return true;
61     }
62 
63     bool binary(json::binary_t& val) override
64     {
65         std::string binary_contents = "binary(";
66         std::string comma_space;
67         for (auto b : val)
68         {
69             binary_contents.append(comma_space);
70             binary_contents.append(std::to_string(static_cast<int>(b)));
71             comma_space = ", ";
72         }
73         binary_contents.append(")");
74         events.push_back(binary_contents);
75         return true;
76     }
77 
78     bool start_object(std::size_t elements) override
79     {
80         if (elements == static_cast<std::size_t>(-1))
81         {
82             events.emplace_back("start_object()");
83         }
84         else
85         {
86             events.push_back("start_object(" + std::to_string(elements) + ")");
87         }
88         return true;
89     }
90 
91     bool key(std::string& val) override
92     {
93         events.push_back("key(" + val + ")");
94         return true;
95     }
96 
97     bool end_object() override
98     {
99         events.emplace_back("end_object()");
100         return true;
101     }
102 
103     bool start_array(std::size_t elements) override
104     {
105         if (elements == static_cast<std::size_t>(-1))
106         {
107             events.emplace_back("start_array()");
108         }
109         else
110         {
111             events.push_back("start_array(" + std::to_string(elements) + ")");
112         }
113         return true;
114     }
115 
116     bool end_array() override
117     {
118         events.emplace_back("end_array()");
119         return true;
120     }
121 
122     bool parse_error(std::size_t position, const std::string& /*last_token*/, const json::exception& /*ex*/) override
123     {
124         events.push_back("parse_error(" + std::to_string(position) + ")");
125         return false;
126     }
127 
128     std::vector<std::string> events {};
129 };
130 
131 struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
132 {
133     bool start_object(std::size_t elements) override
134     {
135         if (elements == static_cast<std::size_t>(-1))
136         {
137             events.emplace_back("start_object()");
138         }
139         else
140         {
141             events.push_back("start_object(" + std::to_string(elements) + ")");
142         }
143         return false;
144     }
145 };
146 
147 struct SaxEventLoggerExitAfterKey : public SaxEventLogger
148 {
149     bool key(std::string& val) override
150     {
151         events.push_back("key(" + val + ")");
152         return false;
153     }
154 };
155 
156 struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
157 {
158     bool start_array(std::size_t elements) override
159     {
160         if (elements == static_cast<std::size_t>(-1))
161         {
162             events.emplace_back("start_array()");
163         }
164         else
165         {
166             events.push_back("start_array(" + std::to_string(elements) + ")");
167         }
168         return false;
169     }
170 };
171 
172 template <typename T>
173 class proxy_iterator
174 {
175   public:
176     using iterator = typename T::iterator;
177     using value_type = typename std::iterator_traits<iterator>::value_type;
178     using reference = typename std::iterator_traits<iterator>::reference;
179     using pointer = typename std::iterator_traits<iterator>::pointer;
180     using difference_type =
181         typename std::iterator_traits<iterator>::difference_type;
182     using iterator_category = std::input_iterator_tag;
183 
184     proxy_iterator() = default;
proxy_iterator(iterator& it)185     explicit proxy_iterator(iterator& it) : m_it(std::addressof(it)) {}
186 
operator ++()187     proxy_iterator& operator++()
188     {
189         ++*m_it;
190         return *this;
191     }
192 
operator --()193     proxy_iterator& operator--()
194     {
195         --*m_it;
196         return *this;
197     }
198 
operator ==(const proxy_iterator& rhs) const199     bool operator==(const proxy_iterator& rhs) const
200     {
201         return (m_it && rhs.m_it) ? (*m_it == *rhs.m_it) : (m_it == rhs.m_it);
202     }
203 
operator !=(const proxy_iterator& rhs) const204     bool operator!=(const proxy_iterator& rhs) const
205     {
206         return !(*this == rhs);
207     }
208 
operator *() const209     reference operator*() const
210     {
211         return **m_it;
212     }
213 
214   private:
215     iterator* m_it = nullptr;
216 };
217 } // namespace
218 
219 TEST_CASE("deserialization")
220 {
221     SECTION("successful deserialization")
222     {
223         SECTION("stream")
224         {
225             std::stringstream ss1;
226             std::stringstream ss2;
227             std::stringstream ss3;
228             ss1 << R"(["foo",1,2,3,false,{"one":1}])";
229             ss2 << R"(["foo",1,2,3,false,{"one":1}])";
230             ss3 << R"(["foo",1,2,3,false,{"one":1}])";
231             json j = json::parse(ss1);
232             CHECK(json::accept(ss2));
233             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
234 
235             SaxEventLogger l;
236             CHECK(json::sax_parse(ss3, &l));
237             CHECK(l.events.size() == 11);
238             CHECK(l.events == std::vector<std::string>(
239             {
240                 "start_array()", "string(foo)", "number_unsigned(1)",
241                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
242                 "start_object()", "key(one)", "number_unsigned(1)",
243                 "end_object()", "end_array()"
244             }));
245         }
246 
247         SECTION("string literal")
248         {
249             const auto* s = R"(["foo",1,2,3,false,{"one":1}])";
250             json j = json::parse(s);
251             CHECK(json::accept(s));
252             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
253 
254             SaxEventLogger l;
255             CHECK(json::sax_parse(s, &l));
256             CHECK(l.events.size() == 11);
257             CHECK(l.events == std::vector<std::string>(
258             {
259                 "start_array()", "string(foo)", "number_unsigned(1)",
260                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
261                 "start_object()", "key(one)", "number_unsigned(1)",
262                 "end_object()", "end_array()"
263             }));
264         }
265 
266         SECTION("string_t")
267         {
268             json::string_t s = R"(["foo",1,2,3,false,{"one":1}])";
269             json j = json::parse(s);
270             CHECK(json::accept(s));
271             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
272 
273             SaxEventLogger l;
274             CHECK(json::sax_parse(s, &l));
275             CHECK(l.events.size() == 11);
276             CHECK(l.events == std::vector<std::string>(
277             {
278                 "start_array()", "string(foo)", "number_unsigned(1)",
279                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
280                 "start_object()", "key(one)", "number_unsigned(1)",
281                 "end_object()", "end_array()"
282             }));
283         }
284 
285         SECTION("operator<<")
286         {
287             std::stringstream ss;
288             ss << R"(["foo",1,2,3,false,{"one":1}])";
289             json j;
290             j << ss;
291             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
292         }
293 
294         SECTION("operator>>")
295         {
296             std::stringstream ss;
297             ss << R"(["foo",1,2,3,false,{"one":1}])";
298             json j;
299             ss >> j;
300             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
301         }
302 
303         SECTION("user-defined string literal")
304         {
305             CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
306         }
307     }
308 
309     SECTION("unsuccessful deserialization")
310     {
311         SECTION("stream")
312         {
313             std::stringstream ss1;
314             std::stringstream ss3;
315             std::stringstream ss4;
316             std::stringstream ss5;
317             ss1 << R"(["foo",1,2,3,false,{"one":1})";
318             ss3 << R"(["foo",1,2,3,false,{"one":1})";
319             ss4 << R"(["foo",1,2,3,false,{"one":1})";
320             ss5 << R"(["foo",1,2,3,false,{"one":1})";
321 
322             json _;
323             CHECK_THROWS_WITH_AS(_ = json::parse(ss1), "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
324             CHECK(!json::accept(ss3));
325 
326             json j_error;
327             CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false));
328             CHECK(j_error.is_discarded());
329 
330             SaxEventLogger l;
331             CHECK(!json::sax_parse(ss5, &l));
332             CHECK(l.events.size() == 11);
333             CHECK(l.events == std::vector<std::string>(
334             {
335                 "start_array()", "string(foo)", "number_unsigned(1)",
336                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
337                 "start_object()", "key(one)", "number_unsigned(1)",
338                 "end_object()", "parse_error(29)"
339             }));
340         }
341 
342         SECTION("string")
343         {
344             json::string_t s = R"(["foo",1,2,3,false,{"one":1})";
345             json _;
346             CHECK_THROWS_WITH_AS(_ = json::parse(s), "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
347             CHECK(!json::accept(s));
348 
349             json j_error;
350             CHECK_NOTHROW(j_error = json::parse(s, nullptr, false));
351             CHECK(j_error.is_discarded());
352 
353             SaxEventLogger l;
354             CHECK(!json::sax_parse(s, &l));
355             CHECK(l.events.size() == 11);
356             CHECK(l.events == std::vector<std::string>(
357             {
358                 "start_array()", "string(foo)", "number_unsigned(1)",
359                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
360                 "start_object()", "key(one)", "number_unsigned(1)",
361                 "end_object()", "parse_error(29)"
362             }));
363         }
364 
365         SECTION("operator<<")
366         {
367             std::stringstream ss;
368             ss << R"(["foo",1,2,3,false,{"one":1})";
369             json j;
370             CHECK_THROWS_WITH_AS(j << ss, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
371         }
372 
373         SECTION("operator>>")
374         {
375             std::stringstream ss;
376             ss << R"(["foo",1,2,3,false,{"one":1})";
377             json j;
378             CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
379         }
380 
381         SECTION("user-defined string literal")
382         {
383             CHECK_THROWS_WITH_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
384         }
385     }
386 
387     SECTION("contiguous containers")
388     {
389         SECTION("directly")
390         {
391             SECTION("from std::vector")
392             {
393                 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
394                 CHECK(json::parse(v) == json(true));
395                 CHECK(json::accept(v));
396 
397                 SaxEventLogger l;
398                 CHECK(json::sax_parse(v, &l));
399                 CHECK(l.events.size() == 1);
400                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
401             }
402 
403             SECTION("from std::array")
404             {
405                 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
406                 CHECK(json::parse(v) == json(true));
407                 CHECK(json::accept(v));
408 
409                 SaxEventLogger l;
410                 CHECK(json::sax_parse(v, &l));
411                 CHECK(l.events.size() == 1);
412                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
413             }
414 
415             SECTION("from array")
416             {
417                 uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
418                 CHECK(json::parse(v) == json(true));
419                 CHECK(json::accept(v));
420 
421                 SaxEventLogger l;
422                 CHECK(json::sax_parse(v, &l));
423                 CHECK(l.events.size() == 1);
424                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
425             }
426 
427             SECTION("from chars")
428             {
429                 auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)
430                 v[0] = 't';
431                 v[1] = 'r';
432                 v[2] = 'u';
433                 v[3] = 'e';
434                 v[4] = '\0';
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                 delete[] v; // NOLINT(cppcoreguidelines-owning-memory)
444             }
445 
446             SECTION("from std::string")
447             {
448                 std::string v = {'t', 'r', 'u', 'e'};
449                 CHECK(json::parse(v) == json(true));
450                 CHECK(json::accept(v));
451 
452                 SaxEventLogger l;
453                 CHECK(json::sax_parse(v, &l));
454                 CHECK(l.events.size() == 1);
455                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
456             }
457 
458             SECTION("from std::initializer_list")
459             {
460                 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
461                 CHECK(json::parse(v) == json(true));
462                 CHECK(json::accept(v));
463 
464                 SaxEventLogger l;
465                 CHECK(json::sax_parse(v, &l));
466                 CHECK(l.events.size() == 1);
467                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
468             }
469 
470             SECTION("empty container")
471             {
472                 std::vector<uint8_t> v;
473                 json _;
474                 CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&);
475                 CHECK(!json::accept(v));
476 
477                 SaxEventLogger l;
478                 CHECK(!json::sax_parse(v, &l));
479                 CHECK(l.events.size() == 1);
480                 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
481             }
482         }
483 
484         SECTION("via iterator range")
485         {
486             SECTION("from std::vector")
487             {
488                 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
489                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
490                 CHECK(json::accept(std::begin(v), std::end(v)));
491 
492                 SaxEventLogger l;
493                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
494                 CHECK(l.events.size() == 1);
495                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
496 
497             }
498 
499             SECTION("from std::array")
500             {
501                 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
502                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
503                 CHECK(json::accept(std::begin(v), std::end(v)));
504 
505                 SaxEventLogger l;
506                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
507                 CHECK(l.events.size() == 1);
508                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
509             }
510 
511             SECTION("from array")
512             {
513                 uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
514                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
515                 CHECK(json::accept(std::begin(v), std::end(v)));
516 
517                 SaxEventLogger l;
518                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
519                 CHECK(l.events.size() == 1);
520                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
521             }
522 
523             SECTION("from std::string")
524             {
525                 std::string v = {'t', 'r', 'u', 'e'};
526                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
527                 CHECK(json::accept(std::begin(v), std::end(v)));
528 
529                 SaxEventLogger l;
530                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
531                 CHECK(l.events.size() == 1);
532                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
533             }
534 
535             SECTION("from std::initializer_list")
536             {
537                 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
538                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
539                 CHECK(json::accept(std::begin(v), std::end(v)));
540 
541                 SaxEventLogger l;
542                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
543                 CHECK(l.events.size() == 1);
544                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
545             }
546 
547             SECTION("from std::valarray")
548             {
549                 std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
550                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
551                 CHECK(json::accept(std::begin(v), std::end(v)));
552 
553                 SaxEventLogger l;
554                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
555                 CHECK(l.events.size() == 1);
556                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
557             }
558 
559             SECTION("with empty range")
560             {
561                 std::vector<uint8_t> v;
562                 json _;
563                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
564                 CHECK(!json::accept(std::begin(v), std::end(v)));
565 
566                 SaxEventLogger l;
567                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
568                 CHECK(l.events.size() == 1);
569                 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
570             }
571 
572             SECTION("iterator_input_adapter advances iterators correctly")
573             {
574                 using nlohmann::json;
575                 using nlohmann::detail::input_format_t;
576                 using nlohmann::detail::json_sax_dom_parser;
577                 using proxy = proxy_iterator<std::string>;
578 
579                 std::string str1 = "[1]";
580                 std::string str2 = "[2]";
581                 std::string str = str1 + str2;
582 
583                 auto first = str.begin();
584                 auto last = str.end();
585                 json j;
586                 json_sax_dom_parser<json> sax(j, true);
587 
588                 CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
589                                       input_format_t::json, false));
590                 CHECK(j.dump() == str1);
591                 CHECK(std::string(first, last) == str2);
592             }
593         }
594 
595         // these cases are required for 100% line coverage
596         SECTION("error cases")
597         {
598             SECTION("case 1")
599             {
600                 std::array<std::uint8_t, 9> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}};
601                 json _;
602                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
603                 CHECK(!json::accept(std::begin(v), std::end(v)));
604 
605                 json j_error;
606                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
607                 CHECK(j_error.is_discarded());
608 
609                 SaxEventLogger l;
610                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
611                 CHECK(l.events.size() == 1);
612                 CHECK(l.events == std::vector<std::string>({"parse_error(10)"}));
613             }
614 
615             SECTION("case 2")
616             {
617                 std::array<std::uint8_t, 10> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}};
618                 json _;
619                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
620                 CHECK(!json::accept(std::begin(v), std::end(v)));
621 
622                 json j_error;
623                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
624                 CHECK(j_error.is_discarded());
625 
626                 SaxEventLogger l;
627                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
628                 CHECK(l.events.size() == 1);
629                 CHECK(l.events == std::vector<std::string>({"parse_error(11)"}));
630             }
631 
632             SECTION("case 3")
633             {
634                 std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}};
635                 json _;
636                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
637                 CHECK(!json::accept(std::begin(v), std::end(v)));
638 
639                 json j_error;
640                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
641                 CHECK(j_error.is_discarded());
642 
643                 SaxEventLogger l;
644                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
645                 CHECK(l.events.size() == 1);
646                 CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
647             }
648 
649             SECTION("case 4")
650             {
651                 std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}};
652                 json _;
653                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
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(18)"}));
664             }
665 
666             SECTION("case 5")
667             {
668                 std::array<std::uint8_t, 3> v = {{'\"', 0x7F, 0xC1}};
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(3)"}));
681             }
682 
683             SECTION("case 6")
684             {
685                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 0x7F}};
686                 json _;
687                 CHECK_THROWS_WITH_AS(_ = json::parse(std::begin(v), std::end(v)), "[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'", 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 7")
701             {
702                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 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 8")
718             {
719                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xE0, 0x9F}};
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 9")
735             {
736                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xEF, 0xC0}};
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 10")
752             {
753                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xED, 0x7F}};
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 11")
769             {
770                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 0x8F}};
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 12")
786             {
787                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 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 13")
803             {
804                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 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 14")
820             {
821                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 0xC0}};
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() == 1);
833                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
834             }
835 
836             SECTION("case 15")
837             {
838                 std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF4, 0x7F}};
839                 json _;
840                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
841                 CHECK(!json::accept(std::begin(v), std::end(v)));
842 
843                 json j_error;
844                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
845                 CHECK(j_error.is_discarded());
846 
847                 SaxEventLogger l;
848                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
849                 CHECK(l.events.size() == 1);
850                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
851             }
852 
853             SECTION("case 16")
854             {
855                 std::array<std::uint8_t, 6> v = {{'{', '\"', '\"', ':', '1', '1'}};
856                 json _;
857                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
858                 CHECK(!json::accept(std::begin(v), std::end(v)));
859 
860                 json j_error;
861                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
862                 CHECK(j_error.is_discarded());
863 
864                 SaxEventLogger l;
865                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
866                 CHECK(l.events.size() == 4);
867                 CHECK(l.events == std::vector<std::string>(
868                 {
869                     "start_object()", "key()", "number_unsigned(11)",
870                     "parse_error(7)"
871                 }));
872             }
873         }
874     }
875 
876     SECTION("ignoring byte-order marks")
877     {
878         std::string bom = "\xEF\xBB\xBF";
879 
880         SECTION("BOM only")
881         {
882             json _;
883             CHECK_THROWS_WITH_AS(_ = json::parse(bom), "[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", json::parse_error&);
884 
885             CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom)), "[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", json::parse_error&);
886 
887             SaxEventLogger l;
888             CHECK(!json::sax_parse(bom, &l));
889             CHECK(l.events.size() == 1);
890             CHECK(l.events == std::vector<std::string>(
891             {
892                 "parse_error(4)"
893             }));
894         }
895 
896         SECTION("BOM and content")
897         {
898             CHECK(json::parse(bom + "1") == 1);
899             CHECK(json::parse(std::istringstream(bom + "1")) == 1);
900 
901             SaxEventLogger l1;
902             SaxEventLogger l2;
903             CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1));
904             CHECK(json::sax_parse(bom + "1", &l2));
905             CHECK(l1.events.size() == 1);
906             CHECK(l1.events == std::vector<std::string>(
907             {
908                 "number_unsigned(1)"
909             }));
910             CHECK(l2.events.size() == 1);
911             CHECK(l2.events == std::vector<std::string>(
912             {
913                 "number_unsigned(1)"
914             }));
915         }
916 
917         SECTION("2 byte of BOM")
918         {
919             json _;
920             CHECK_THROWS_WITH_AS(_ = json::parse(bom.substr(0, 2)), "[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'", json::parse_error&);
921 
922             CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), "[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'", json::parse_error&);
923 
924             SaxEventLogger l1;
925             SaxEventLogger l2;
926             CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
927             CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
928             CHECK(l1.events.size() == 1);
929             CHECK(l1.events == std::vector<std::string>(
930             {
931                 "parse_error(3)"
932             }));
933             CHECK(l2.events.size() == 1);
934             CHECK(l2.events == std::vector<std::string>(
935             {
936                 "parse_error(3)"
937             }));
938         }
939 
940         SECTION("1 byte of BOM")
941         {
942             json _;
943             CHECK_THROWS_WITH_AS(_ = json::parse(bom.substr(0, 1)), "[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'", json::parse_error&);
944 
945             CHECK_THROWS_WITH_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), "[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'", json::parse_error&);
946 
947             SaxEventLogger l1;
948             SaxEventLogger l2;
949             CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));
950             CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
951             CHECK(l1.events.size() == 1);
952             CHECK(l1.events == std::vector<std::string>(
953             {
954                 "parse_error(2)"
955             }));
956             CHECK(l2.events.size() == 1);
957             CHECK(l2.events == std::vector<std::string>(
958             {
959                 "parse_error(2)"
960             }));
961         }
962 
963         SECTION("variations")
964         {
965             // calculate variations of each byte of the BOM to make sure
966             // that the BOM and only the BOM is skipped
967             for (int i0 = -1; i0 < 2; ++i0)
968             {
969                 for (int i1 = -1; i1 < 2; ++i1)
970                 {
971                     for (int i2 = -1; i2 < 2; ++i2)
972                     {
973                         // debug output for the variations
974                         CAPTURE(i0)
975                         CAPTURE(i1)
976                         CAPTURE(i2)
977 
978                         std::string s;
979                         s.push_back(static_cast<char>(bom[0] + i0));
980                         s.push_back(static_cast<char>(bom[1] + i1));
981                         s.push_back(static_cast<char>(bom[2] + i2));
982 
983                         if (i0 == 0 && i1 == 0 && i2 == 0)
984                         {
985                             // without any variation, we skip the BOM
986                             CHECK(json::parse(s + "null") == json());
987                             CHECK(json::parse(std::istringstream(s + "null")) == json());
988 
989                             SaxEventLogger l;
990                             CHECK(json::sax_parse(s + "null", &l));
991                             CHECK(l.events.size() == 1);
992                             CHECK(l.events == std::vector<std::string>(
993                             {
994                                 "null()"
995                             }));
996                         }
997                         else
998                         {
999                             // any variation is an error
1000                             json _;
1001                             CHECK_THROWS_AS(_ = json::parse(s + "null"), json::parse_error&);
1002                             CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + "null")), json::parse_error&);
1003 
1004                             SaxEventLogger l;
1005                             CHECK(!json::sax_parse(s + "null", &l));
1006                             CHECK(l.events.size() == 1);
1007 
1008                             if (i0 != 0)
1009                             {
1010                                 CHECK(l.events == std::vector<std::string>(
1011                                 {
1012                                     "parse_error(1)"
1013                                 }));
1014                             }
1015                             else if (i1 != 0)
1016                             {
1017                                 CHECK(l.events == std::vector<std::string>(
1018                                 {
1019                                     "parse_error(2)"
1020                                 }));
1021                             }
1022                             else
1023                             {
1024                                 CHECK(l.events == std::vector<std::string>(
1025                                 {
1026                                     "parse_error(3)"
1027                                 }));
1028                             }
1029                         }
1030                     }
1031                 }
1032             }
1033         }
1034 
1035         SECTION("preserve state after parsing")
1036         {
1037             std::istringstream s(bom + "123 456");
1038             json j;
1039             j << s;
1040             CHECK(j == 123);
1041             j << s;
1042             CHECK(j == 456);
1043         }
1044     }
1045 
1046     SECTION("SAX and early abort")
1047     {
1048         std::string s = R"([1, ["string", 43.12], null, {"key1": true, "key2": false}])";
1049 
1050         SaxEventLogger default_logger;
1051         SaxEventLoggerExitAfterStartObject exit_after_start_object;
1052         SaxEventLoggerExitAfterKey exit_after_key;
1053         SaxEventLoggerExitAfterStartArray exit_after_start_array;
1054 
1055         json::sax_parse(s, &default_logger);
1056         CHECK(default_logger.events.size() == 14);
1057         CHECK(default_logger.events == std::vector<std::string>(
1058         {
1059             "start_array()", "number_unsigned(1)", "start_array()",
1060             "string(string)", "number_float(43.12)", "end_array()", "null()",
1061             "start_object()", "key(key1)", "boolean(true)", "key(key2)",
1062             "boolean(false)", "end_object()", "end_array()"
1063         }));
1064 
1065         json::sax_parse(s, &exit_after_start_object);
1066         CHECK(exit_after_start_object.events.size() == 8);
1067         CHECK(exit_after_start_object.events == std::vector<std::string>(
1068         {
1069             "start_array()", "number_unsigned(1)", "start_array()",
1070             "string(string)", "number_float(43.12)", "end_array()", "null()",
1071             "start_object()"
1072         }));
1073 
1074         json::sax_parse(s, &exit_after_key);
1075         CHECK(exit_after_key.events.size() == 9);
1076         CHECK(exit_after_key.events == std::vector<std::string>(
1077         {
1078             "start_array()", "number_unsigned(1)", "start_array()",
1079             "string(string)", "number_float(43.12)", "end_array()", "null()",
1080             "start_object()", "key(key1)"
1081         }));
1082 
1083         json::sax_parse(s, &exit_after_start_array);
1084         CHECK(exit_after_start_array.events.size() == 1);
1085         CHECK(exit_after_start_array.events == std::vector<std::string>(
1086         {
1087             "start_array()"
1088         }));
1089     }
1090 
1091     SECTION("JSON Lines")
1092     {
1093         SECTION("Example file")
1094         {
1095             std::stringstream ss;
1096             ss << R"({"name": "Gilbert", "wins": [["straight", "7"], ["one pair", "10"]]}
1097                     {"name": "Alexa", "wins": [["two pair", "4"], ["two pair", "9"]]}
1098                     {"name": "May", "wins": []}
1099                     {"name": "Deloise", "wins": [["three of a kind", "5"]]}
1100 )";
1101 
1102             std::string line;
1103             int object_count = 0;
1104             while (std::getline(ss, line))
1105             {
1106                 ++object_count;
1107                 CHECK(json::accept(line));
1108             }
1109 
1110             CHECK(object_count == 4);
1111         }
1112 
1113         SECTION("Example file without trailing newline")
1114         {
1115             std::stringstream ss;
1116             ss << R"({"name": "Gilbert", "wins": [["straight", "7"], ["one pair", "10"]]}
1117                     {"name": "Alexa", "wins": [["two pair", "4"], ["two pair", "9"]]}
1118                     {"name": "May", "wins": []}
1119                     {"name": "Deloise", "wins": [["three of a kind", "5"]]})";
1120 
1121             std::string line;
1122             int object_count = 0;
1123             while (std::getline(ss, line))
1124             {
1125                 ++object_count;
1126                 CHECK(json::accept(line));
1127             }
1128 
1129             CHECK(object_count == 4);
1130         }
1131     }
1132 }
1133 
1134 TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
1135                    char, unsigned char, signed char,
1136                    wchar_t,
1137                    char16_t, char32_t,
1138                    std::uint8_t, std::int8_t,
1139                    std::int16_t, std::uint16_t,
1140                    std::int32_t, std::uint32_t)
1141 {
1142     std::vector<T> v = {'t', 'r', 'u', 'e'};
1143     CHECK(json::parse(v) == json(true));
1144     CHECK(json::accept(v));
1145 
1146     SaxEventLogger l;
1147     CHECK(json::sax_parse(v, &l));
1148     CHECK(l.events.size() == 1);
1149     CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
1150 }
1151 
1152 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
1153                    char, unsigned char, std::uint8_t)
1154 {
1155     // a star emoji
1156     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), '"'};
1157     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1158     CHECK(json::accept(v));
1159 
1160     SaxEventLogger l;
1161     CHECK(json::sax_parse(v, &l));
1162     CHECK(l.events.size() == 1);
1163 }
1164 
1165 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
1166                    char16_t, std::uint16_t)
1167 {
1168     // a star emoji
1169     std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1170     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1171     CHECK(json::accept(v));
1172 
1173     SaxEventLogger l;
1174     CHECK(json::sax_parse(v, &l));
1175     CHECK(l.events.size() == 1);
1176 }
1177 
1178 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T,
1179                    char32_t, std::uint32_t)
1180 {
1181     // a star emoji
1182     std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1183     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1184     CHECK(json::accept(v));
1185 
1186     SaxEventLogger l;
1187     CHECK(json::sax_parse(v, &l));
1188     CHECK(l.events.size() == 1);
1189 }
1190