• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
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-2019 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 {
null__anon947d98360111::SaxEventLogger43     bool null() override
44     {
45         events.push_back("null()");
46         return true;
47     }
48 
boolean__anon947d98360111::SaxEventLogger49     bool boolean(bool val) override
50     {
51         events.push_back(val ? "boolean(true)" : "boolean(false)");
52         return true;
53     }
54 
number_integer__anon947d98360111::SaxEventLogger55     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 
number_unsigned__anon947d98360111::SaxEventLogger61     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 
number_float__anon947d98360111::SaxEventLogger67     bool number_float(json::number_float_t, const std::string& s) override
68     {
69         events.push_back("number_float(" + s + ")");
70         return true;
71     }
72 
string__anon947d98360111::SaxEventLogger73     bool string(std::string& val) override
74     {
75         events.push_back("string(" + val + ")");
76         return true;
77     }
78 
binary__anon947d98360111::SaxEventLogger79     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 
start_object__anon947d98360111::SaxEventLogger94     bool start_object(std::size_t elements) override
95     {
96         if (elements == std::size_t(-1))
97         {
98             events.push_back("start_object()");
99         }
100         else
101         {
102             events.push_back("start_object(" + std::to_string(elements) + ")");
103         }
104         return true;
105     }
106 
key__anon947d98360111::SaxEventLogger107     bool key(std::string& val) override
108     {
109         events.push_back("key(" + val + ")");
110         return true;
111     }
112 
end_object__anon947d98360111::SaxEventLogger113     bool end_object() override
114     {
115         events.push_back("end_object()");
116         return true;
117     }
118 
start_array__anon947d98360111::SaxEventLogger119     bool start_array(std::size_t elements) override
120     {
121         if (elements == std::size_t(-1))
122         {
123             events.push_back("start_array()");
124         }
125         else
126         {
127             events.push_back("start_array(" + std::to_string(elements) + ")");
128         }
129         return true;
130     }
131 
end_array__anon947d98360111::SaxEventLogger132     bool end_array() override
133     {
134         events.push_back("end_array()");
135         return true;
136     }
137 
parse_error__anon947d98360111::SaxEventLogger138     bool parse_error(std::size_t position, const std::string&, const json::exception&) 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 {
start_object__anon947d98360111::SaxEventLoggerExitAfterStartObject149     bool start_object(std::size_t elements) override
150     {
151         if (elements == std::size_t(-1))
152         {
153             events.push_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 {
key__anon947d98360111::SaxEventLoggerExitAfterKey165     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 {
start_array__anon947d98360111::SaxEventLoggerExitAfterStartArray174     bool start_array(std::size_t elements) override
175     {
176         if (elements == std::size_t(-1))
177         {
178             events.push_back("start_array()");
179         }
180         else
181         {
182             events.push_back("start_array(" + std::to_string(elements) + ")");
183         }
184         return false;
185     }
186 };
187 }
188 
189 TEST_CASE("deserialization")
190 {
191     SECTION("successful deserialization")
192     {
193         SECTION("stream")
194         {
195             std::stringstream ss1, ss2, ss3;
196             ss1 << "[\"foo\",1,2,3,false,{\"one\":1}]";
197             ss2 << "[\"foo\",1,2,3,false,{\"one\":1}]";
198             ss3 << "[\"foo\",1,2,3,false,{\"one\":1}]";
199             json j = json::parse(ss1);
200             CHECK(json::accept(ss2));
201             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
202 
203             SaxEventLogger l;
204             CHECK(json::sax_parse(ss3, &l));
205             CHECK(l.events.size() == 11);
206             CHECK(l.events == std::vector<std::string>(
207             {
208                 "start_array()", "string(foo)", "number_unsigned(1)",
209                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
210                 "start_object()", "key(one)", "number_unsigned(1)",
211                 "end_object()", "end_array()"
212             }));
213         }
214 
215         SECTION("string literal")
216         {
217             auto s = "[\"foo\",1,2,3,false,{\"one\":1}]";
218             json j = json::parse(s);
219             CHECK(json::accept(s));
220             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
221 
222             SaxEventLogger l;
223             CHECK(json::sax_parse(s, &l));
224             CHECK(l.events.size() == 11);
225             CHECK(l.events == std::vector<std::string>(
226             {
227                 "start_array()", "string(foo)", "number_unsigned(1)",
228                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
229                 "start_object()", "key(one)", "number_unsigned(1)",
230                 "end_object()", "end_array()"
231             }));
232         }
233 
234         SECTION("string_t")
235         {
236             json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}]";
237             json j = json::parse(s);
238             CHECK(json::accept(s));
239             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
240 
241             SaxEventLogger l;
242             CHECK(json::sax_parse(s, &l));
243             CHECK(l.events.size() == 11);
244             CHECK(l.events == std::vector<std::string>(
245             {
246                 "start_array()", "string(foo)", "number_unsigned(1)",
247                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
248                 "start_object()", "key(one)", "number_unsigned(1)",
249                 "end_object()", "end_array()"
250             }));
251         }
252 
253         SECTION("operator<<")
254         {
255             std::stringstream ss;
256             ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
257             json j;
258             j << ss;
259             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
260         }
261 
262         SECTION("operator>>")
263         {
264             std::stringstream ss;
265             ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
266             json j;
267             ss >> j;
268             CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
269         }
270 
271         SECTION("user-defined string literal")
272         {
273             CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
274         }
275     }
276 
277     SECTION("unsuccessful deserialization")
278     {
279         SECTION("stream")
280         {
281             std::stringstream ss1, ss2, ss3, ss4, ss5;
282             ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
283             ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
284             ss3 << "[\"foo\",1,2,3,false,{\"one\":1}";
285             ss4 << "[\"foo\",1,2,3,false,{\"one\":1}";
286             ss5 << "[\"foo\",1,2,3,false,{\"one\":1}";
287 
288             json _;
289             CHECK_THROWS_AS(_ = json::parse(ss1), json::parse_error&);
290             CHECK_THROWS_WITH(_ = json::parse(ss2),
291                               "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
292             CHECK(!json::accept(ss3));
293 
294             json j_error;
295             CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false));
296             CHECK(j_error.is_discarded());
297 
298             SaxEventLogger l;
299             CHECK(!json::sax_parse(ss5, &l));
300             CHECK(l.events.size() == 11);
301             CHECK(l.events == std::vector<std::string>(
302             {
303                 "start_array()", "string(foo)", "number_unsigned(1)",
304                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
305                 "start_object()", "key(one)", "number_unsigned(1)",
306                 "end_object()", "parse_error(29)"
307             }));
308         }
309 
310         SECTION("string")
311         {
312             json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
313             json _;
314             CHECK_THROWS_AS(_ = json::parse(s), json::parse_error&);
315             CHECK_THROWS_WITH(_ = json::parse(s),
316                               "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
317             CHECK(!json::accept(s));
318 
319             json j_error;
320             CHECK_NOTHROW(j_error = json::parse(s, nullptr, false));
321             CHECK(j_error.is_discarded());
322 
323             SaxEventLogger l;
324             CHECK(!json::sax_parse(s, &l));
325             CHECK(l.events.size() == 11);
326             CHECK(l.events == std::vector<std::string>(
327             {
328                 "start_array()", "string(foo)", "number_unsigned(1)",
329                 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
330                 "start_object()", "key(one)", "number_unsigned(1)",
331                 "end_object()", "parse_error(29)"
332             }));
333         }
334 
335         SECTION("operator<<")
336         {
337             std::stringstream ss1, ss2;
338             ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
339             ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
340             json j;
341             CHECK_THROWS_AS(j << ss1, json::parse_error&);
342             CHECK_THROWS_WITH(j << ss2,
343                               "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
344         }
345 
346         SECTION("operator>>")
347         {
348             std::stringstream ss1, ss2;
349             ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
350             ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
351             json j;
352             CHECK_THROWS_AS(ss1 >> j, json::parse_error&);
353             CHECK_THROWS_WITH(ss2 >> j,
354                               "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
355         }
356 
357         SECTION("user-defined string literal")
358         {
359             CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&);
360             CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
361                               "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'");
362         }
363     }
364 
365     SECTION("contiguous containers")
366     {
367         SECTION("directly")
368         {
369             SECTION("from std::vector")
370             {
371                 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
372                 CHECK(json::parse(v) == json(true));
373                 CHECK(json::accept(v));
374 
375                 SaxEventLogger l;
376                 CHECK(json::sax_parse(v, &l));
377                 CHECK(l.events.size() == 1);
378                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
379             }
380 
381             SECTION("from std::array")
382             {
383                 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
384                 CHECK(json::parse(v) == json(true));
385                 CHECK(json::accept(v));
386 
387                 SaxEventLogger l;
388                 CHECK(json::sax_parse(v, &l));
389                 CHECK(l.events.size() == 1);
390                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
391             }
392 
393             SECTION("from array")
394             {
395                 uint8_t v[] = {'t', 'r', 'u', 'e'};
396                 CHECK(json::parse(v) == json(true));
397                 CHECK(json::accept(v));
398 
399                 SaxEventLogger l;
400                 CHECK(json::sax_parse(v, &l));
401                 CHECK(l.events.size() == 1);
402                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
403             }
404 
405             SECTION("from chars")
406             {
407                 uint8_t* v = new uint8_t[5];
408                 v[0] = 't';
409                 v[1] = 'r';
410                 v[2] = 'u';
411                 v[3] = 'e';
412                 v[4] = '\0';
413                 CHECK(json::parse(v) == json(true));
414                 CHECK(json::accept(v));
415 
416                 SaxEventLogger l;
417                 CHECK(json::sax_parse(v, &l));
418                 CHECK(l.events.size() == 1);
419                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
420 
421                 delete[] v;
422             }
423 
424             SECTION("from std::string")
425             {
426                 std::string v = {'t', 'r', 'u', 'e'};
427                 CHECK(json::parse(v) == json(true));
428                 CHECK(json::accept(v));
429 
430                 SaxEventLogger l;
431                 CHECK(json::sax_parse(v, &l));
432                 CHECK(l.events.size() == 1);
433                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
434             }
435 
436             SECTION("from std::initializer_list")
437             {
438                 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
439                 CHECK(json::parse(v) == json(true));
440                 CHECK(json::accept(v));
441 
442                 SaxEventLogger l;
443                 CHECK(json::sax_parse(v, &l));
444                 CHECK(l.events.size() == 1);
445                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
446             }
447 
448             SECTION("empty container")
449             {
450                 std::vector<uint8_t> v;
451                 json _;
452                 CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&);
453                 CHECK(!json::accept(v));
454 
455                 SaxEventLogger l;
456                 CHECK(!json::sax_parse(v, &l));
457                 CHECK(l.events.size() == 1);
458                 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
459             }
460         }
461 
462         SECTION("via iterator range")
463         {
464             SECTION("from std::vector")
465             {
466                 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
467                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
468                 CHECK(json::accept(std::begin(v), std::end(v)));
469 
470                 SaxEventLogger l;
471                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
472                 CHECK(l.events.size() == 1);
473                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
474 
475             }
476 
477             SECTION("from std::array")
478             {
479                 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} };
480                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
481                 CHECK(json::accept(std::begin(v), std::end(v)));
482 
483                 SaxEventLogger l;
484                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
485                 CHECK(l.events.size() == 1);
486                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
487             }
488 
489             SECTION("from array")
490             {
491                 uint8_t v[] = {'t', 'r', 'u', 'e'};
492                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
493                 CHECK(json::accept(std::begin(v), std::end(v)));
494 
495                 SaxEventLogger l;
496                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
497                 CHECK(l.events.size() == 1);
498                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
499             }
500 
501             SECTION("from std::string")
502             {
503                 std::string v = {'t', 'r', 'u', 'e'};
504                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
505                 CHECK(json::accept(std::begin(v), std::end(v)));
506 
507                 SaxEventLogger l;
508                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
509                 CHECK(l.events.size() == 1);
510                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
511             }
512 
513             SECTION("from std::initializer_list")
514             {
515                 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'};
516                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
517                 CHECK(json::accept(std::begin(v), std::end(v)));
518 
519                 SaxEventLogger l;
520                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
521                 CHECK(l.events.size() == 1);
522                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
523             }
524 
525             SECTION("from std::valarray")
526             {
527                 std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'};
528                 CHECK(json::parse(std::begin(v), std::end(v)) == json(true));
529                 CHECK(json::accept(std::begin(v), std::end(v)));
530 
531                 SaxEventLogger l;
532                 CHECK(json::sax_parse(std::begin(v), std::end(v), &l));
533                 CHECK(l.events.size() == 1);
534                 CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
535             }
536 
537             SECTION("with empty range")
538             {
539                 std::vector<uint8_t> v;
540                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
541                 CHECK(!json::accept(std::begin(v), std::end(v)));
542 
543                 SaxEventLogger l;
544                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
545                 CHECK(l.events.size() == 1);
546                 CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
547             }
548         }
549 
550         // these cases are required for 100% line coverage
551         SECTION("error cases")
552         {
553             SECTION("case 1")
554             {
555                 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
556                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
557                 CHECK(!json::accept(std::begin(v), std::end(v)));
558 
559                 json j_error;
560                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
561                 CHECK(j_error.is_discarded());
562 
563                 SaxEventLogger l;
564                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
565                 CHECK(l.events.size() == 1);
566                 CHECK(l.events == std::vector<std::string>({"parse_error(10)"}));
567             }
568 
569             SECTION("case 2")
570             {
571                 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
572                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
573                 CHECK(!json::accept(std::begin(v), std::end(v)));
574 
575                 json j_error;
576                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
577                 CHECK(j_error.is_discarded());
578 
579                 SaxEventLogger l;
580                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
581                 CHECK(l.events.size() == 1);
582                 CHECK(l.events == std::vector<std::string>({"parse_error(11)"}));
583             }
584 
585             SECTION("case 3")
586             {
587                 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
588                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
589                 CHECK(!json::accept(std::begin(v), std::end(v)));
590 
591                 json j_error;
592                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
593                 CHECK(j_error.is_discarded());
594 
595                 SaxEventLogger l;
596                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
597                 CHECK(l.events.size() == 1);
598                 CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
599             }
600 
601             SECTION("case 4")
602             {
603                 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
604                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
605                 CHECK(!json::accept(std::begin(v), std::end(v)));
606 
607                 json j_error;
608                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
609                 CHECK(j_error.is_discarded());
610 
611                 SaxEventLogger l;
612                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
613                 CHECK(l.events.size() == 1);
614                 CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
615             }
616 
617             SECTION("case 5")
618             {
619                 uint8_t v[] = {'\"', 0x7F, 0xC1};
620                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
621                 CHECK(!json::accept(std::begin(v), std::end(v)));
622 
623                 json j_error;
624                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
625                 CHECK(j_error.is_discarded());
626 
627                 SaxEventLogger l;
628                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
629                 CHECK(l.events.size() == 1);
630                 CHECK(l.events == std::vector<std::string>({"parse_error(3)"}));
631             }
632 
633             SECTION("case 6")
634             {
635                 uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
636                 json _;
637                 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
638                 CHECK_THROWS_WITH(_ = json::parse(std::begin(v), std::end(v)),
639                                   "[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'");
640                 CHECK(!json::accept(std::begin(v), std::end(v)));
641 
642                 json j_error;
643                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
644                 CHECK(j_error.is_discarded());
645 
646                 SaxEventLogger l;
647                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
648                 CHECK(l.events.size() == 1);
649                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
650             }
651 
652             SECTION("case 7")
653             {
654                 uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
655                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
656                 CHECK(!json::accept(std::begin(v), std::end(v)));
657 
658                 json j_error;
659                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
660                 CHECK(j_error.is_discarded());
661 
662                 SaxEventLogger l;
663                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
664                 CHECK(l.events.size() == 1);
665                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
666             }
667 
668             SECTION("case 8")
669             {
670                 uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
671                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
672                 CHECK(!json::accept(std::begin(v), std::end(v)));
673 
674                 json j_error;
675                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
676                 CHECK(j_error.is_discarded());
677 
678                 SaxEventLogger l;
679                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
680                 CHECK(l.events.size() == 1);
681                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
682             }
683 
684             SECTION("case 9")
685             {
686                 uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
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 10")
701             {
702                 uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
703                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
704                 CHECK(!json::accept(std::begin(v), std::end(v)));
705 
706                 json j_error;
707                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
708                 CHECK(j_error.is_discarded());
709 
710                 SaxEventLogger l;
711                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
712                 CHECK(l.events.size() == 1);
713                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
714             }
715 
716             SECTION("case 11")
717             {
718                 uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
719                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
720                 CHECK(!json::accept(std::begin(v), std::end(v)));
721 
722                 json j_error;
723                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
724                 CHECK(j_error.is_discarded());
725 
726                 SaxEventLogger l;
727                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
728                 CHECK(l.events.size() == 1);
729                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
730             }
731 
732             SECTION("case 12")
733             {
734                 uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
735                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
736                 CHECK(!json::accept(std::begin(v), std::end(v)));
737 
738                 json j_error;
739                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
740                 CHECK(j_error.is_discarded());
741 
742                 SaxEventLogger l;
743                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
744                 CHECK(l.events.size() == 1);
745                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
746             }
747 
748             SECTION("case 13")
749             {
750                 uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
751                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
752                 CHECK(!json::accept(std::begin(v), std::end(v)));
753 
754                 json j_error;
755                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
756                 CHECK(j_error.is_discarded());
757 
758                 SaxEventLogger l;
759                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
760                 CHECK(l.events.size() == 1);
761                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
762             }
763 
764             SECTION("case 14")
765             {
766                 uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
767                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
768                 CHECK(!json::accept(std::begin(v), std::end(v)));
769 
770                 json j_error;
771                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
772                 CHECK(j_error.is_discarded());
773 
774                 SaxEventLogger l;
775                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
776                 CHECK(l.events.size() == 1);
777                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
778             }
779 
780             SECTION("case 15")
781             {
782                 uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
783                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
784                 CHECK(!json::accept(std::begin(v), std::end(v)));
785 
786                 json j_error;
787                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
788                 CHECK(j_error.is_discarded());
789 
790                 SaxEventLogger l;
791                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
792                 CHECK(l.events.size() == 1);
793                 CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
794             }
795 
796             SECTION("case 16")
797             {
798                 uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'};
799                 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
800                 CHECK(!json::accept(std::begin(v), std::end(v)));
801 
802                 json j_error;
803                 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
804                 CHECK(j_error.is_discarded());
805 
806                 SaxEventLogger l;
807                 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
808                 CHECK(l.events.size() == 4);
809                 CHECK(l.events == std::vector<std::string>(
810                 {
811                     "start_object()", "key()", "number_unsigned(11)",
812                     "parse_error(7)"
813                 }));
814             }
815         }
816     }
817 
818     SECTION("ignoring byte-order marks")
819     {
820         std::string bom = "\xEF\xBB\xBF";
821 
822         SECTION("BOM only")
823         {
824             json _;
825             CHECK_THROWS_AS(_ = json::parse(bom), json::parse_error&);
826             CHECK_THROWS_WITH(_ = json::parse(bom),
827                               "[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");
828 
829             CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom)), json::parse_error&);
830             CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom)),
831                               "[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");
832 
833             SaxEventLogger l;
834             CHECK(!json::sax_parse(bom, &l));
835             CHECK(l.events.size() == 1);
836             CHECK(l.events == std::vector<std::string>(
837             {
838                 "parse_error(4)"
839             }));
840         }
841 
842         SECTION("BOM and content")
843         {
844             CHECK(json::parse(bom + "1") == 1);
845             CHECK(json::parse(std::istringstream(bom + "1")) == 1);
846 
847             SaxEventLogger l1, l2;
848             CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1));
849             CHECK(json::sax_parse(bom + "1", &l2));
850             CHECK(l1.events.size() == 1);
851             CHECK(l1.events == std::vector<std::string>(
852             {
853                 "number_unsigned(1)"
854             }));
855             CHECK(l2.events.size() == 1);
856             CHECK(l2.events == std::vector<std::string>(
857             {
858                 "number_unsigned(1)"
859             }));
860         }
861 
862         SECTION("2 byte of BOM")
863         {
864             json _;
865             CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 2)), json::parse_error&);
866             CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 2)),
867                               "[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'");
868 
869             CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&);
870             CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 2))),
871                               "[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'");
872 
873             SaxEventLogger l1, l2;
874             CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1));
875             CHECK(!json::sax_parse(bom.substr(0, 2), &l2));
876             CHECK(l1.events.size() == 1);
877             CHECK(l1.events == std::vector<std::string>(
878             {
879                 "parse_error(3)"
880             }));
881             CHECK(l2.events.size() == 1);
882             CHECK(l2.events == std::vector<std::string>(
883             {
884                 "parse_error(3)"
885             }));
886         }
887 
888         SECTION("1 byte of BOM")
889         {
890             json _;
891             CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 1)), json::parse_error&);
892             CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 1)),
893                               "[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'");
894 
895             CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&);
896             CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 1))),
897                               "[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'");
898 
899             SaxEventLogger l1, l2;
900             CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1));
901             CHECK(!json::sax_parse(bom.substr(0, 1), &l2));
902             CHECK(l1.events.size() == 1);
903             CHECK(l1.events == std::vector<std::string>(
904             {
905                 "parse_error(2)"
906             }));
907             CHECK(l2.events.size() == 1);
908             CHECK(l2.events == std::vector<std::string>(
909             {
910                 "parse_error(2)"
911             }));
912         }
913 
914         SECTION("variations")
915         {
916             // calculate variations of each byte of the BOM to make sure
917             // that the BOM and only the BOM is skipped
918             for (int i0 = -1; i0 < 2; ++i0)
919             {
920                 for (int i1 = -1; i1 < 2; ++i1)
921                 {
922                     for (int i2 = -1; i2 < 2; ++i2)
923                     {
924                         // debug output for the variations
925                         CAPTURE(i0)
926                         CAPTURE(i1)
927                         CAPTURE(i2)
928 
929                         std::string s = "";
930                         s.push_back(static_cast<char>(bom[0] + i0));
931                         s.push_back(static_cast<char>(bom[1] + i1));
932                         s.push_back(static_cast<char>(bom[2] + i2));
933 
934                         if (i0 == 0 && i1 == 0 && i2 == 0)
935                         {
936                             // without any variation, we skip the BOM
937                             CHECK(json::parse(s + "null") == json());
938                             CHECK(json::parse(std::istringstream(s + "null")) == json());
939 
940                             SaxEventLogger l;
941                             CHECK(json::sax_parse(s + "null", &l));
942                             CHECK(l.events.size() == 1);
943                             CHECK(l.events == std::vector<std::string>(
944                             {
945                                 "null()"
946                             }));
947                         }
948                         else
949                         {
950                             // any variation is an error
951                             json _;
952                             CHECK_THROWS_AS(_ = json::parse(s + "null"), json::parse_error&);
953                             CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + "null")), json::parse_error&);
954 
955                             SaxEventLogger l;
956                             CHECK(!json::sax_parse(s + "null", &l));
957                             CHECK(l.events.size() == 1);
958 
959                             if (i0 != 0)
960                             {
961                                 CHECK(l.events == std::vector<std::string>(
962                                 {
963                                     "parse_error(1)"
964                                 }));
965                             }
966                             else if (i1 != 0)
967                             {
968                                 CHECK(l.events == std::vector<std::string>(
969                                 {
970                                     "parse_error(2)"
971                                 }));
972                             }
973                             else
974                             {
975                                 CHECK(l.events == std::vector<std::string>(
976                                 {
977                                     "parse_error(3)"
978                                 }));
979                             }
980                         }
981                     }
982                 }
983             }
984         }
985 
986         SECTION("preserve state after parsing")
987         {
988             std::istringstream s(bom + "123 456");
989             json j;
990             j << s;
991             CHECK(j == 123);
992             j << s;
993             CHECK(j == 456);
994         }
995     }
996 
997     SECTION("SAX and early abort")
998     {
999         std::string s = "[1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}]";
1000 
1001         SaxEventLogger default_logger;
1002         SaxEventLoggerExitAfterStartObject exit_after_start_object;
1003         SaxEventLoggerExitAfterKey exit_after_key;
1004         SaxEventLoggerExitAfterStartArray exit_after_start_array;
1005 
1006         json::sax_parse(s, &default_logger);
1007         CHECK(default_logger.events.size() == 14);
1008         CHECK(default_logger.events == std::vector<std::string>(
1009         {
1010             "start_array()", "number_unsigned(1)", "start_array()",
1011             "string(string)", "number_float(43.12)", "end_array()", "null()",
1012             "start_object()", "key(key1)", "boolean(true)", "key(key2)",
1013             "boolean(false)", "end_object()", "end_array()"
1014         }));
1015 
1016         json::sax_parse(s, &exit_after_start_object);
1017         CHECK(exit_after_start_object.events.size() == 8);
1018         CHECK(exit_after_start_object.events == std::vector<std::string>(
1019         {
1020             "start_array()", "number_unsigned(1)", "start_array()",
1021             "string(string)", "number_float(43.12)", "end_array()", "null()",
1022             "start_object()"
1023         }));
1024 
1025         json::sax_parse(s, &exit_after_key);
1026         CHECK(exit_after_key.events.size() == 9);
1027         CHECK(exit_after_key.events == std::vector<std::string>(
1028         {
1029             "start_array()", "number_unsigned(1)", "start_array()",
1030             "string(string)", "number_float(43.12)", "end_array()", "null()",
1031             "start_object()", "key(key1)"
1032         }));
1033 
1034         json::sax_parse(s, &exit_after_start_array);
1035         CHECK(exit_after_start_array.events.size() == 1);
1036         CHECK(exit_after_start_array.events == std::vector<std::string>(
1037         {
1038             "start_array()"
1039         }));
1040     }
1041 }
1042 
1043 TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,
1044                    char, unsigned char, signed char,
1045                    wchar_t,
1046                    char16_t, char32_t,
1047                    std::uint8_t, std::int8_t,
1048                    std::int16_t, std::uint16_t,
1049                    std::int32_t, std::uint32_t)
1050 {
1051     std::vector<T> v = {'t', 'r', 'u', 'e'};
1052     CHECK(json::parse(v) == json(true));
1053     CHECK(json::accept(v));
1054 
1055     SaxEventLogger l;
1056     CHECK(json::sax_parse(v, &l));
1057     CHECK(l.events.size() == 1);
1058     CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
1059 }
1060 
1061 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
1062                    char, unsigned char, std::uint8_t)
1063 {
1064     // a star emoji
1065     std::vector<T> v = {'"', static_cast<T>(0xe2), static_cast<T>(0xad), static_cast<T>(0x90), static_cast<T>(0xef), static_cast<T>(0xb8), static_cast<T>(0x8f), '"'};
1066     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1067     CHECK(json::accept(v));
1068 
1069     SaxEventLogger l;
1070     CHECK(json::sax_parse(v, &l));
1071     CHECK(l.events.size() == 1);
1072 }
1073 
1074 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T,
1075                    char16_t, std::uint16_t)
1076 {
1077     // a star emoji
1078     std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1079     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1080     CHECK(json::accept(v));
1081 
1082     SaxEventLogger l;
1083     CHECK(json::sax_parse(v, &l));
1084     CHECK(l.events.size() == 1);
1085 }
1086 
1087 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T,
1088                    char32_t, std::uint32_t)
1089 {
1090     // a star emoji
1091     std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')};
1092     CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
1093     CHECK(json::accept(v));
1094 
1095     SaxEventLogger l;
1096     CHECK(json::sax_parse(v, &l));
1097     CHECK(l.events.size() == 1);
1098 }
1099