• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //     __ _____ _____ _____
2 //  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3 // |  |  |__   |  |  | | | |  version 3.11.2
4 // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 #include "doctest_compatibility.h"
10 
11 #include <nlohmann/json.hpp>
12 using nlohmann::json;
13 
14 #include <fstream>
15 #include <sstream>
16 #include <iomanip>
17 #include <iostream>
18 #include <set>
19 #include "make_test_data_available.hpp"
20 #include "test_utils.hpp"
21 
22 namespace
23 {
24 class SaxCountdown
25 {
26   public:
SaxCountdown(const int count)27     explicit SaxCountdown(const int count) : events_left(count)
28     {}
29 
null()30     bool null()
31     {
32         return events_left-- > 0;
33     }
34 
boolean(bool)35     bool boolean(bool /*unused*/)
36     {
37         return events_left-- > 0;
38     }
39 
number_integer(json::number_integer_t)40     bool number_integer(json::number_integer_t /*unused*/)
41     {
42         return events_left-- > 0;
43     }
44 
number_unsigned(json::number_unsigned_t)45     bool number_unsigned(json::number_unsigned_t /*unused*/)
46     {
47         return events_left-- > 0;
48     }
49 
number_float(json::number_float_t,const std::string &)50     bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
51     {
52         return events_left-- > 0;
53     }
54 
string(std::string &)55     bool string(std::string& /*unused*/)
56     {
57         return events_left-- > 0;
58     }
59 
binary(std::vector<std::uint8_t> &)60     bool binary(std::vector<std::uint8_t>& /*unused*/)
61     {
62         return events_left-- > 0;
63     }
64 
start_object(std::size_t)65     bool start_object(std::size_t /*unused*/)
66     {
67         return events_left-- > 0;
68     }
69 
key(std::string &)70     bool key(std::string& /*unused*/)
71     {
72         return events_left-- > 0;
73     }
74 
end_object()75     bool end_object()
76     {
77         return events_left-- > 0;
78     }
79 
start_array(std::size_t)80     bool start_array(std::size_t /*unused*/)
81     {
82         return events_left-- > 0;
83     }
84 
end_array()85     bool end_array()
86     {
87         return events_left-- > 0;
88     }
89 
parse_error(std::size_t,const std::string &,const json::exception &)90     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
91     {
92         return false;
93     }
94 
95   private:
96     int events_left = 0;
97 };
98 } // namespace
99 
100 TEST_CASE("CBOR")
101 {
102     SECTION("individual values")
103     {
104         SECTION("discarded")
105         {
106             // discarded values are not serialized
107             json j = json::value_t::discarded;
108             const auto result = json::to_cbor(j);
109             CHECK(result.empty());
110         }
111 
112         SECTION("NaN")
113         {
114             // NaN value
115             json j = std::numeric_limits<json::number_float_t>::quiet_NaN();
116             std::vector<uint8_t> expected = {0xf9, 0x7e, 0x00};
117             const auto result = json::to_cbor(j);
118             CHECK(result == expected);
119         }
120 
121         SECTION("Infinity")
122         {
123             // Infinity value
124             json j = std::numeric_limits<json::number_float_t>::infinity();
125             std::vector<uint8_t> expected = {0xf9, 0x7c, 0x00};
126             const auto result = json::to_cbor(j);
127             CHECK(result == expected);
128         }
129 
130         SECTION("null")
131         {
132             json j = nullptr;
133             std::vector<uint8_t> expected = {0xf6};
134             const auto result = json::to_cbor(j);
135             CHECK(result == expected);
136 
137             // roundtrip
138             CHECK(json::from_cbor(result) == j);
139             CHECK(json::from_cbor(result, true, false) == j);
140         }
141 
142         SECTION("boolean")
143         {
144             SECTION("true")
145             {
146                 json j = true;
147                 std::vector<uint8_t> expected = {0xf5};
148                 const auto result = json::to_cbor(j);
149                 CHECK(result == expected);
150 
151                 // roundtrip
152                 CHECK(json::from_cbor(result) == j);
153                 CHECK(json::from_cbor(result, true, false) == j);
154             }
155 
156             SECTION("false")
157             {
158                 json j = false;
159                 std::vector<uint8_t> expected = {0xf4};
160                 const auto result = json::to_cbor(j);
161                 CHECK(result == expected);
162 
163                 // roundtrip
164                 CHECK(json::from_cbor(result) == j);
165                 CHECK(json::from_cbor(result, true, false) == j);
166             }
167         }
168 
169         SECTION("number")
170         {
171             SECTION("signed")
172             {
173                 SECTION("-9223372036854775808..-4294967297")
174                 {
175                     std::vector<int64_t> numbers;
176                     numbers.push_back(INT64_MIN);
177                     numbers.push_back(-1000000000000000000);
178                     numbers.push_back(-100000000000000000);
179                     numbers.push_back(-10000000000000000);
180                     numbers.push_back(-1000000000000000);
181                     numbers.push_back(-100000000000000);
182                     numbers.push_back(-10000000000000);
183                     numbers.push_back(-1000000000000);
184                     numbers.push_back(-100000000000);
185                     numbers.push_back(-10000000000);
186                     numbers.push_back(-4294967297);
187                     for (auto i : numbers)
188                     {
189                         CAPTURE(i)
190 
191                         // create JSON value with integer number
192                         json j = i;
193 
194                         // check type
195                         CHECK(j.is_number_integer());
196 
197                         // create expected byte vector
198                         std::vector<uint8_t> expected;
199                         expected.push_back(static_cast<uint8_t>(0x3b));
200                         auto positive = static_cast<uint64_t>(-1 - i);
201                         expected.push_back(static_cast<uint8_t>((positive >> 56) & 0xff));
202                         expected.push_back(static_cast<uint8_t>((positive >> 48) & 0xff));
203                         expected.push_back(static_cast<uint8_t>((positive >> 40) & 0xff));
204                         expected.push_back(static_cast<uint8_t>((positive >> 32) & 0xff));
205                         expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));
206                         expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));
207                         expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
208                         expected.push_back(static_cast<uint8_t>(positive & 0xff));
209 
210                         // compare result + size
211                         const auto result = json::to_cbor(j);
212                         CHECK(result == expected);
213                         CHECK(result.size() == 9);
214 
215                         // check individual bytes
216                         CHECK(result[0] == 0x3b);
217                         uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
218                                             (static_cast<uint64_t>(result[2]) << 060) +
219                                             (static_cast<uint64_t>(result[3]) << 050) +
220                                             (static_cast<uint64_t>(result[4]) << 040) +
221                                             (static_cast<uint64_t>(result[5]) << 030) +
222                                             (static_cast<uint64_t>(result[6]) << 020) +
223                                             (static_cast<uint64_t>(result[7]) << 010) +
224                                             static_cast<uint64_t>(result[8]);
225                         CHECK(restored == positive);
226                         CHECK(-1 - static_cast<int64_t>(restored) == i);
227 
228                         // roundtrip
229                         CHECK(json::from_cbor(result) == j);
230                         CHECK(json::from_cbor(result, true, false) == j);
231                     }
232                 }
233 
234                 SECTION("-4294967296..-65537")
235                 {
236                     std::vector<int64_t> numbers;
237                     numbers.push_back(-65537);
238                     numbers.push_back(-100000);
239                     numbers.push_back(-1000000);
240                     numbers.push_back(-10000000);
241                     numbers.push_back(-100000000);
242                     numbers.push_back(-1000000000);
243                     numbers.push_back(-4294967296);
244                     for (auto i : numbers)
245                     {
246                         CAPTURE(i)
247 
248                         // create JSON value with integer number
249                         json j = i;
250 
251                         // check type
252                         CHECK(j.is_number_integer());
253 
254                         // create expected byte vector
255                         std::vector<uint8_t> expected;
256                         expected.push_back(static_cast<uint8_t>(0x3a));
257                         auto positive = static_cast<uint32_t>(static_cast<uint64_t>(-1 - i) & 0x00000000ffffffff);
258                         expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));
259                         expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));
260                         expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
261                         expected.push_back(static_cast<uint8_t>(positive & 0xff));
262 
263                         // compare result + size
264                         const auto result = json::to_cbor(j);
265                         CHECK(result == expected);
266                         CHECK(result.size() == 5);
267 
268                         // check individual bytes
269                         CHECK(result[0] == 0x3a);
270                         uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
271                                             (static_cast<uint32_t>(result[2]) << 020) +
272                                             (static_cast<uint32_t>(result[3]) << 010) +
273                                             static_cast<uint32_t>(result[4]);
274                         CHECK(restored == positive);
275                         CHECK(-1LL - restored == i);
276 
277                         // roundtrip
278                         CHECK(json::from_cbor(result) == j);
279                         CHECK(json::from_cbor(result, true, false) == j);
280                     }
281                 }
282 
283                 SECTION("-65536..-257")
284                 {
285                     for (int32_t i = -65536; i <= -257; ++i)
286                     {
287                         CAPTURE(i)
288 
289                         // create JSON value with integer number
290                         json j = i;
291 
292                         // check type
293                         CHECK(j.is_number_integer());
294 
295                         // create expected byte vector
296                         std::vector<uint8_t> expected;
297                         expected.push_back(static_cast<uint8_t>(0x39));
298                         auto positive = static_cast<uint16_t>(-1 - i);
299                         expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
300                         expected.push_back(static_cast<uint8_t>(positive & 0xff));
301 
302                         // compare result + size
303                         const auto result = json::to_cbor(j);
304                         CHECK(result == expected);
305                         CHECK(result.size() == 3);
306 
307                         // check individual bytes
308                         CHECK(result[0] == 0x39);
309                         auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
310                         CHECK(restored == positive);
311                         CHECK(-1 - restored == i);
312 
313                         // roundtrip
314                         CHECK(json::from_cbor(result) == j);
315                         CHECK(json::from_cbor(result, true, false) == j);
316                     }
317                 }
318 
319                 SECTION("-9263 (int 16)")
320                 {
321                     json j = -9263;
322                     std::vector<uint8_t> expected = {0x39, 0x24, 0x2e};
323 
324                     const auto result = json::to_cbor(j);
325                     CHECK(result == expected);
326 
327                     auto restored = static_cast<int16_t>(-1 - ((result[1] << 8) + result[2]));
328                     CHECK(restored == -9263);
329 
330                     // roundtrip
331                     CHECK(json::from_cbor(result) == j);
332                     CHECK(json::from_cbor(result, true, false) == j);
333                 }
334 
335                 SECTION("-256..-24")
336                 {
337                     for (auto i = -256; i < -24; ++i)
338                     {
339                         CAPTURE(i)
340 
341                         // create JSON value with integer number
342                         json j = i;
343 
344                         // check type
345                         CHECK(j.is_number_integer());
346 
347                         // create expected byte vector
348                         std::vector<uint8_t> expected;
349                         expected.push_back(0x38);
350                         expected.push_back(static_cast<uint8_t>(-1 - i));
351 
352                         // compare result + size
353                         const auto result = json::to_cbor(j);
354                         CHECK(result == expected);
355                         CHECK(result.size() == 2);
356 
357                         // check individual bytes
358                         CHECK(result[0] == 0x38);
359                         CHECK(static_cast<int16_t>(-1 - result[1]) == i);
360 
361                         // roundtrip
362                         CHECK(json::from_cbor(result) == j);
363                         CHECK(json::from_cbor(result, true, false) == j);
364                     }
365                 }
366 
367                 SECTION("-24..-1")
368                 {
369                     for (auto i = -24; i <= -1; ++i)
370                     {
371                         CAPTURE(i)
372 
373                         // create JSON value with integer number
374                         json j = i;
375 
376                         // check type
377                         CHECK(j.is_number_integer());
378 
379                         // create expected byte vector
380                         std::vector<uint8_t> expected;
381                         expected.push_back(static_cast<uint8_t>(0x20 - 1 - static_cast<uint8_t>(i)));
382 
383                         // compare result + size
384                         const auto result = json::to_cbor(j);
385                         CHECK(result == expected);
386                         CHECK(result.size() == 1);
387 
388                         // check individual bytes
389                         CHECK(static_cast<int8_t>(0x20 - 1 - result[0]) == i);
390 
391                         // roundtrip
392                         CHECK(json::from_cbor(result) == j);
393                         CHECK(json::from_cbor(result, true, false) == j);
394                     }
395                 }
396 
397                 SECTION("0..23")
398                 {
399                     for (size_t i = 0; i <= 23; ++i)
400                     {
401                         CAPTURE(i)
402 
403                         // create JSON value with integer number
404                         json j = -1;
405                         j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
406 
407                         // check type
408                         CHECK(j.is_number_integer());
409 
410                         // create expected byte vector
411                         std::vector<uint8_t> expected;
412                         expected.push_back(static_cast<uint8_t>(i));
413 
414                         // compare result + size
415                         const auto result = json::to_cbor(j);
416                         CHECK(result == expected);
417                         CHECK(result.size() == 1);
418 
419                         // check individual bytes
420                         CHECK(result[0] == i);
421 
422                         // roundtrip
423                         CHECK(json::from_cbor(result) == j);
424                         CHECK(json::from_cbor(result, true, false) == j);
425                     }
426                 }
427 
428                 SECTION("24..255")
429                 {
430                     for (size_t i = 24; i <= 255; ++i)
431                     {
432                         CAPTURE(i)
433 
434                         // create JSON value with integer number
435                         json j = -1;
436                         j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
437 
438                         // check type
439                         CHECK(j.is_number_integer());
440 
441                         // create expected byte vector
442                         std::vector<uint8_t> expected;
443                         expected.push_back(static_cast<uint8_t>(0x18));
444                         expected.push_back(static_cast<uint8_t>(i));
445 
446                         // compare result + size
447                         const auto result = json::to_cbor(j);
448                         CHECK(result == expected);
449                         CHECK(result.size() == 2);
450 
451                         // check individual bytes
452                         CHECK(result[0] == 0x18);
453                         CHECK(result[1] == i);
454 
455                         // roundtrip
456                         CHECK(json::from_cbor(result) == j);
457                         CHECK(json::from_cbor(result, true, false) == j);
458                     }
459                 }
460 
461                 SECTION("256..65535")
462                 {
463                     for (size_t i = 256; i <= 65535; ++i)
464                     {
465                         CAPTURE(i)
466 
467                         // create JSON value with integer number
468                         json j = -1;
469                         j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
470 
471                         // check type
472                         CHECK(j.is_number_integer());
473 
474                         // create expected byte vector
475                         std::vector<uint8_t> expected;
476                         expected.push_back(static_cast<uint8_t>(0x19));
477                         expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
478                         expected.push_back(static_cast<uint8_t>(i & 0xff));
479 
480                         // compare result + size
481                         const auto result = json::to_cbor(j);
482                         CHECK(result == expected);
483                         CHECK(result.size() == 3);
484 
485                         // check individual bytes
486                         CHECK(result[0] == 0x19);
487                         auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
488                         CHECK(restored == i);
489 
490                         // roundtrip
491                         CHECK(json::from_cbor(result) == j);
492                         CHECK(json::from_cbor(result, true, false) == j);
493                     }
494                 }
495 
496                 SECTION("65536..4294967295")
497                 {
498                     for (uint32_t i :
499                             {
500                                 65536u, 77777u, 1048576u
501                             })
502                     {
503                         CAPTURE(i)
504 
505                         // create JSON value with integer number
506                         json j = -1;
507                         j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
508 
509                         // check type
510                         CHECK(j.is_number_integer());
511 
512                         // create expected byte vector
513                         std::vector<uint8_t> expected;
514                         expected.push_back(0x1a);
515                         expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
516                         expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
517                         expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
518                         expected.push_back(static_cast<uint8_t>(i & 0xff));
519 
520                         // compare result + size
521                         const auto result = json::to_cbor(j);
522                         CHECK(result == expected);
523                         CHECK(result.size() == 5);
524 
525                         // check individual bytes
526                         CHECK(result[0] == 0x1a);
527                         uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
528                                             (static_cast<uint32_t>(result[2]) << 020) +
529                                             (static_cast<uint32_t>(result[3]) << 010) +
530                                             static_cast<uint32_t>(result[4]);
531                         CHECK(restored == i);
532 
533                         // roundtrip
534                         CHECK(json::from_cbor(result) == j);
535                         CHECK(json::from_cbor(result, true, false) == j);
536                     }
537                 }
538 
539                 SECTION("4294967296..4611686018427387903")
540                 {
541                     for (uint64_t i :
542                             {
543                                 4294967296ul, 4611686018427387903ul
544                             })
545                     {
546                         CAPTURE(i)
547 
548                         // create JSON value with integer number
549                         json j = -1;
550                         j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
551 
552                         // check type
553                         CHECK(j.is_number_integer());
554 
555                         // create expected byte vector
556                         std::vector<uint8_t> expected;
557                         expected.push_back(0x1b);
558                         expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
559                         expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
560                         expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
561                         expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
562                         expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
563                         expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
564                         expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
565                         expected.push_back(static_cast<uint8_t>(i & 0xff));
566 
567                         // compare result + size
568                         const auto result = json::to_cbor(j);
569                         CHECK(result == expected);
570                         CHECK(result.size() == 9);
571 
572                         // check individual bytes
573                         CHECK(result[0] == 0x1b);
574                         uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
575                                             (static_cast<uint64_t>(result[2]) << 060) +
576                                             (static_cast<uint64_t>(result[3]) << 050) +
577                                             (static_cast<uint64_t>(result[4]) << 040) +
578                                             (static_cast<uint64_t>(result[5]) << 030) +
579                                             (static_cast<uint64_t>(result[6]) << 020) +
580                                             (static_cast<uint64_t>(result[7]) << 010) +
581                                             static_cast<uint64_t>(result[8]);
582                         CHECK(restored == i);
583 
584                         // roundtrip
585                         CHECK(json::from_cbor(result) == j);
586                         CHECK(json::from_cbor(result, true, false) == j);
587                     }
588                 }
589 
590                 SECTION("-32768..-129 (int 16)")
591                 {
592                     for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)
593                     {
594                         CAPTURE(i)
595 
596                         // create JSON value with integer number
597                         json j = i;
598 
599                         // check type
600                         CHECK(j.is_number_integer());
601 
602                         // create expected byte vector
603                         std::vector<uint8_t> expected;
604                         expected.push_back(0xd1);
605                         expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
606                         expected.push_back(static_cast<uint8_t>(i & 0xff));
607 
608                         // compare result + size
609                         const auto result = json::to_msgpack(j);
610                         CHECK(result == expected);
611                         CHECK(result.size() == 3);
612 
613                         // check individual bytes
614                         CHECK(result[0] == 0xd1);
615                         auto restored = static_cast<int16_t>((result[1] << 8) + result[2]);
616                         CHECK(restored == i);
617 
618                         // roundtrip
619                         CHECK(json::from_msgpack(result) == j);
620                     }
621                 }
622             }
623 
624             SECTION("unsigned")
625             {
626                 SECTION("0..23 (Integer)")
627                 {
628                     for (size_t i = 0; i <= 23; ++i)
629                     {
630                         CAPTURE(i)
631 
632                         // create JSON value with unsigned integer number
633                         json j = i;
634 
635                         // check type
636                         CHECK(j.is_number_unsigned());
637 
638                         // create expected byte vector
639                         std::vector<uint8_t> expected;
640                         expected.push_back(static_cast<uint8_t>(i));
641 
642                         // compare result + size
643                         const auto result = json::to_cbor(j);
644                         CHECK(result == expected);
645                         CHECK(result.size() == 1);
646 
647                         // check individual bytes
648                         CHECK(result[0] == i);
649 
650                         // roundtrip
651                         CHECK(json::from_cbor(result) == j);
652                         CHECK(json::from_cbor(result, true, false) == j);
653                     }
654                 }
655 
656                 SECTION("24..255 (one-byte uint8_t)")
657                 {
658                     for (size_t i = 24; i <= 255; ++i)
659                     {
660                         CAPTURE(i)
661 
662                         // create JSON value with unsigned integer number
663                         json j = i;
664 
665                         // check type
666                         CHECK(j.is_number_unsigned());
667 
668                         // create expected byte vector
669                         std::vector<uint8_t> expected;
670                         expected.push_back(0x18);
671                         expected.push_back(static_cast<uint8_t>(i));
672 
673                         // compare result + size
674                         const auto result = json::to_cbor(j);
675                         CHECK(result == expected);
676                         CHECK(result.size() == 2);
677 
678                         // check individual bytes
679                         CHECK(result[0] == 0x18);
680                         auto restored = static_cast<uint8_t>(result[1]);
681                         CHECK(restored == i);
682 
683                         // roundtrip
684                         CHECK(json::from_cbor(result) == j);
685                         CHECK(json::from_cbor(result, true, false) == j);
686                     }
687                 }
688 
689                 SECTION("256..65535 (two-byte uint16_t)")
690                 {
691                     for (size_t i = 256; i <= 65535; ++i)
692                     {
693                         CAPTURE(i)
694 
695                         // create JSON value with unsigned integer number
696                         json j = i;
697 
698                         // check type
699                         CHECK(j.is_number_unsigned());
700 
701                         // create expected byte vector
702                         std::vector<uint8_t> expected;
703                         expected.push_back(0x19);
704                         expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
705                         expected.push_back(static_cast<uint8_t>(i & 0xff));
706 
707                         // compare result + size
708                         const auto result = json::to_cbor(j);
709                         CHECK(result == expected);
710                         CHECK(result.size() == 3);
711 
712                         // check individual bytes
713                         CHECK(result[0] == 0x19);
714                         auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
715                         CHECK(restored == i);
716 
717                         // roundtrip
718                         CHECK(json::from_cbor(result) == j);
719                         CHECK(json::from_cbor(result, true, false) == j);
720                     }
721                 }
722 
723                 SECTION("65536..4294967295 (four-byte uint32_t)")
724                 {
725                     for (uint32_t i :
726                             {
727                                 65536u, 77777u, 1048576u
728                             })
729                     {
730                         CAPTURE(i)
731 
732                         // create JSON value with unsigned integer number
733                         json j = i;
734 
735                         // check type
736                         CHECK(j.is_number_unsigned());
737 
738                         // create expected byte vector
739                         std::vector<uint8_t> expected;
740                         expected.push_back(0x1a);
741                         expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
742                         expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
743                         expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
744                         expected.push_back(static_cast<uint8_t>(i & 0xff));
745 
746                         // compare result + size
747                         const auto result = json::to_cbor(j);
748                         CHECK(result == expected);
749                         CHECK(result.size() == 5);
750 
751                         // check individual bytes
752                         CHECK(result[0] == 0x1a);
753                         uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
754                                             (static_cast<uint32_t>(result[2]) << 020) +
755                                             (static_cast<uint32_t>(result[3]) << 010) +
756                                             static_cast<uint32_t>(result[4]);
757                         CHECK(restored == i);
758 
759                         // roundtrip
760                         CHECK(json::from_cbor(result) == j);
761                         CHECK(json::from_cbor(result, true, false) == j);
762                     }
763                 }
764 
765                 SECTION("4294967296..4611686018427387903 (eight-byte uint64_t)")
766                 {
767                     for (uint64_t i :
768                             {
769                                 4294967296ul, 4611686018427387903ul
770                             })
771                     {
772                         CAPTURE(i)
773 
774                         // create JSON value with integer number
775                         json j = i;
776 
777                         // check type
778                         CHECK(j.is_number_unsigned());
779 
780                         // create expected byte vector
781                         std::vector<uint8_t> expected;
782                         expected.push_back(0x1b);
783                         expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
784                         expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
785                         expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
786                         expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
787                         expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
788                         expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
789                         expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
790                         expected.push_back(static_cast<uint8_t>(i & 0xff));
791 
792                         // compare result + size
793                         const auto result = json::to_cbor(j);
794                         CHECK(result == expected);
795                         CHECK(result.size() == 9);
796 
797                         // check individual bytes
798                         CHECK(result[0] == 0x1b);
799                         uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
800                                             (static_cast<uint64_t>(result[2]) << 060) +
801                                             (static_cast<uint64_t>(result[3]) << 050) +
802                                             (static_cast<uint64_t>(result[4]) << 040) +
803                                             (static_cast<uint64_t>(result[5]) << 030) +
804                                             (static_cast<uint64_t>(result[6]) << 020) +
805                                             (static_cast<uint64_t>(result[7]) << 010) +
806                                             static_cast<uint64_t>(result[8]);
807                         CHECK(restored == i);
808 
809                         // roundtrip
810                         CHECK(json::from_cbor(result) == j);
811                         CHECK(json::from_cbor(result, true, false) == j);
812                     }
813                 }
814             }
815 
816             SECTION("double-precision float")
817             {
818                 SECTION("3.1415925")
819                 {
820                     double v = 3.1415925;
821                     json j = v;
822                     std::vector<uint8_t> expected =
823                     {
824                         0xfb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc
825                     };
826                     const auto result = json::to_cbor(j);
827                     CHECK(result == expected);
828 
829                     // roundtrip
830                     CHECK(json::from_cbor(result) == j);
831                     CHECK(json::from_cbor(result) == v);
832 
833                     CHECK(json::from_cbor(result, true, false) == j);
834                 }
835             }
836 
837             SECTION("single-precision float")
838             {
839                 SECTION("0.5")
840                 {
841                     double v = 0.5;
842                     json j = v;
843                     // its double-precision float binary value is
844                     // {0xfb, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
845                     // but to save memory, we can store it as single-precision float.
846                     std::vector<uint8_t> expected = {0xfa, 0x3f, 0x00, 0x00, 0x00};
847                     const auto result = json::to_cbor(j);
848                     CHECK(result == expected);
849                     // roundtrip
850                     CHECK(json::from_cbor(result) == j);
851                     CHECK(json::from_cbor(result) == v);
852                 }
853                 SECTION("0.0")
854                 {
855                     double v = 0.0;
856                     json j = v;
857                     // its double-precision binary value is:
858                     // {0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
859                     std::vector<uint8_t> expected = {0xfa, 0x00, 0x00, 0x00, 0x00};
860                     const auto result = json::to_cbor(j);
861                     CHECK(result == expected);
862                     // roundtrip
863                     CHECK(json::from_cbor(result) == j);
864                     CHECK(json::from_cbor(result) == v);
865                 }
866                 SECTION("-0.0")
867                 {
868                     double v = -0.0;
869                     json j = v;
870                     // its double-precision binary value is:
871                     // {0xfb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
872                     std::vector<uint8_t> expected = {0xfa, 0x80, 0x00, 0x00, 0x00};
873                     const auto result = json::to_cbor(j);
874                     CHECK(result == expected);
875                     // roundtrip
876                     CHECK(json::from_cbor(result) == j);
877                     CHECK(json::from_cbor(result) == v);
878                 }
879                 SECTION("100.0")
880                 {
881                     double v = 100.0;
882                     json j = v;
883                     // its double-precision binary value is:
884                     // {0xfb, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
885                     std::vector<uint8_t> expected = {0xfa, 0x42, 0xc8, 0x00, 0x00};
886                     const auto result = json::to_cbor(j);
887                     CHECK(result == expected);
888                     // roundtrip
889                     CHECK(json::from_cbor(result) == j);
890                     CHECK(json::from_cbor(result) == v);
891                 }
892                 SECTION("200.0")
893                 {
894                     double v = 200.0;
895                     json j = v;
896                     // its double-precision binary value is:
897                     // {0xfb, 0x40, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
898                     std::vector<uint8_t> expected = {0xfa, 0x43, 0x48, 0x00, 0x00};
899                     const auto result = json::to_cbor(j);
900                     CHECK(result == expected);
901                     // roundtrip
902                     CHECK(json::from_cbor(result) == j);
903                     CHECK(json::from_cbor(result) == v);
904                 }
905                 SECTION("3.40282e+38(max float)")
906                 {
907                     float v = (std::numeric_limits<float>::max)();
908                     json j = v;
909                     std::vector<uint8_t> expected =
910                     {
911                         0xfa, 0x7f, 0x7f, 0xff, 0xff
912                     };
913                     const auto result = json::to_cbor(j);
914                     CHECK(result == expected);
915                     // roundtrip
916                     CHECK(json::from_cbor(result) == j);
917                     CHECK(json::from_cbor(result) == v);
918                 }
919                 SECTION("-3.40282e+38(lowest float)")
920                 {
921                     auto v = static_cast<double>(std::numeric_limits<float>::lowest());
922                     json j = v;
923                     std::vector<uint8_t> expected =
924                     {
925                         0xfa, 0xff, 0x7f, 0xff, 0xff
926                     };
927                     const auto result = json::to_cbor(j);
928                     CHECK(result == expected);
929                     // roundtrip
930                     CHECK(json::from_cbor(result) == j);
931                     CHECK(json::from_cbor(result) == v);
932                 }
933                 SECTION("1 + 3.40282e+38(more than max float)")
934                 {
935                     double v = static_cast<double>((std::numeric_limits<float>::max)()) + 0.1e+34;
936                     json j = v;
937                     std::vector<uint8_t> expected =
938                     {
939                         0xfb, 0x47, 0xf0, 0x00, 0x03, 0x04, 0xdc, 0x64, 0x49
940                     };
941                     // double
942                     const auto result = json::to_cbor(j);
943                     CHECK(result == expected);
944                     // roundtrip
945                     CHECK(json::from_cbor(result) == j);
946                     CHECK(json::from_cbor(result) == v);
947                 }
948                 SECTION("-1 - 3.40282e+38(less than lowest float)")
949                 {
950                     double v = static_cast<double>(std::numeric_limits<float>::lowest()) - 1.0;
951                     json j = v;
952                     std::vector<uint8_t> expected =
953                     {
954                         0xfa, 0xff, 0x7f, 0xff, 0xff
955                     };
956                     // the same with lowest float
957                     const auto result = json::to_cbor(j);
958                     CHECK(result == expected);
959                     // roundtrip
960                     CHECK(json::from_cbor(result) == j);
961                     CHECK(json::from_cbor(result) == v);
962                 }
963 
964             }
965 
966             SECTION("half-precision float (edge cases)")
967             {
968                 SECTION("errors")
969                 {
970                     SECTION("no byte follows")
971                     {
972                         json _;
973                         CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
974                         CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded());
975                     }
976                     SECTION("only one byte follows")
977                     {
978                         json _;
979                         CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
980                         CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded());
981                     }
982                 }
983 
984                 SECTION("exp = 0b00000")
985                 {
986                     SECTION("0 (0 00000 0000000000)")
987                     {
988                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00}));
989                         json::number_float_t d{j};
990                         CHECK(d == 0.0);
991                     }
992 
993                     SECTION("-0 (1 00000 0000000000)")
994                     {
995                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00}));
996                         json::number_float_t d{j};
997                         CHECK(d == -0.0);
998                     }
999 
1000                     SECTION("2**-24 (0 00000 0000000001)")
1001                     {
1002                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x01}));
1003                         json::number_float_t d{j};
1004                         CHECK(d == std::pow(2.0, -24.0));
1005                     }
1006                 }
1007 
1008                 SECTION("exp = 0b11111")
1009                 {
1010                     SECTION("infinity (0 11111 0000000000)")
1011                     {
1012                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));
1013                         json::number_float_t d{j};
1014                         CHECK(d == std::numeric_limits<json::number_float_t>::infinity());
1015                         CHECK(j.dump() == "null");
1016                     }
1017 
1018                     SECTION("-infinity (1 11111 0000000000)")
1019                     {
1020                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xfc, 0x00}));
1021                         json::number_float_t d{j};
1022                         CHECK(d == -std::numeric_limits<json::number_float_t>::infinity());
1023                         CHECK(j.dump() == "null");
1024                     }
1025                 }
1026 
1027                 SECTION("other values from https://en.wikipedia.org/wiki/Half-precision_floating-point_format")
1028                 {
1029                     SECTION("1 (0 01111 0000000000)")
1030                     {
1031                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00}));
1032                         json::number_float_t d{j};
1033                         CHECK(d == 1);
1034                     }
1035 
1036                     SECTION("-2 (1 10000 0000000000)")
1037                     {
1038                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xc0, 0x00}));
1039                         json::number_float_t d{j};
1040                         CHECK(d == -2);
1041                     }
1042 
1043                     SECTION("65504 (0 11110 1111111111)")
1044                     {
1045                         json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff}));
1046                         json::number_float_t d{j};
1047                         CHECK(d == 65504);
1048                     }
1049                 }
1050 
1051                 SECTION("infinity")
1052                 {
1053                     json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));
1054                     json::number_float_t d{j};
1055                     CHECK(!std::isfinite(d));
1056                     CHECK(j.dump() == "null");
1057                 }
1058 
1059                 SECTION("NaN")
1060                 {
1061                     json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7e, 0x00}));
1062                     json::number_float_t d{j};
1063                     CHECK(std::isnan(d));
1064                     CHECK(j.dump() == "null");
1065                 }
1066             }
1067         }
1068 
1069         SECTION("string")
1070         {
1071             SECTION("N = 0..23")
1072             {
1073                 for (size_t N = 0; N <= 0x17; ++N)
1074                 {
1075                     CAPTURE(N)
1076 
1077                     // create JSON value with string containing of N * 'x'
1078                     const auto s = std::string(N, 'x');
1079                     json j = s;
1080 
1081                     // create expected byte vector
1082                     std::vector<uint8_t> expected;
1083                     expected.push_back(static_cast<uint8_t>(0x60 + N));
1084                     for (size_t i = 0; i < N; ++i)
1085                     {
1086                         expected.push_back('x');
1087                     }
1088 
1089                     // compare result + size
1090                     const auto result = json::to_cbor(j);
1091                     CHECK(result == expected);
1092                     CHECK(result.size() == N + 1);
1093                     // check that no null byte is appended
1094                     if (N > 0)
1095                     {
1096                         CHECK(result.back() != '\x00');
1097                     }
1098 
1099                     // roundtrip
1100                     CHECK(json::from_cbor(result) == j);
1101                     CHECK(json::from_cbor(result, true, false) == j);
1102                 }
1103             }
1104 
1105             SECTION("N = 24..255")
1106             {
1107                 for (size_t N = 24; N <= 255; ++N)
1108                 {
1109                     CAPTURE(N)
1110 
1111                     // create JSON value with string containing of N * 'x'
1112                     const auto s = std::string(N, 'x');
1113                     json j = s;
1114 
1115                     // create expected byte vector
1116                     std::vector<uint8_t> expected;
1117                     expected.push_back(0x78);
1118                     expected.push_back(static_cast<uint8_t>(N));
1119                     for (size_t i = 0; i < N; ++i)
1120                     {
1121                         expected.push_back('x');
1122                     }
1123 
1124                     // compare result + size
1125                     const auto result = json::to_cbor(j);
1126                     CHECK(result == expected);
1127                     CHECK(result.size() == N + 2);
1128                     // check that no null byte is appended
1129                     CHECK(result.back() != '\x00');
1130 
1131                     // roundtrip
1132                     CHECK(json::from_cbor(result) == j);
1133                     CHECK(json::from_cbor(result, true, false) == j);
1134                 }
1135             }
1136 
1137             SECTION("N = 256..65535")
1138             {
1139                 for (size_t N :
1140                         {
1141                             256u, 999u, 1025u, 3333u, 2048u, 65535u
1142                         })
1143                 {
1144                     CAPTURE(N)
1145 
1146                     // create JSON value with string containing of N * 'x'
1147                     const auto s = std::string(N, 'x');
1148                     json j = s;
1149 
1150                     // create expected byte vector (hack: create string first)
1151                     std::vector<uint8_t> expected(N, 'x');
1152                     // reverse order of commands, because we insert at begin()
1153                     expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1154                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1155                     expected.insert(expected.begin(), 0x79);
1156 
1157                     // compare result + size
1158                     const auto result = json::to_cbor(j);
1159                     CHECK(result == expected);
1160                     CHECK(result.size() == N + 3);
1161                     // check that no null byte is appended
1162                     CHECK(result.back() != '\x00');
1163 
1164                     // roundtrip
1165                     CHECK(json::from_cbor(result) == j);
1166                     CHECK(json::from_cbor(result, true, false) == j);
1167                 }
1168             }
1169 
1170             SECTION("N = 65536..4294967295")
1171             {
1172                 for (size_t N :
1173                         {
1174                             65536u, 77777u, 1048576u
1175                         })
1176                 {
1177                     CAPTURE(N)
1178 
1179                     // create JSON value with string containing of N * 'x'
1180                     const auto s = std::string(N, 'x');
1181                     json j = s;
1182 
1183                     // create expected byte vector (hack: create string first)
1184                     std::vector<uint8_t> expected(N, 'x');
1185                     // reverse order of commands, because we insert at begin()
1186                     expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1187                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1188                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
1189                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
1190                     expected.insert(expected.begin(), 0x7a);
1191 
1192                     // compare result + size
1193                     const auto result = json::to_cbor(j);
1194                     CHECK(result == expected);
1195                     CHECK(result.size() == N + 5);
1196                     // check that no null byte is appended
1197                     CHECK(result.back() != '\x00');
1198 
1199                     // roundtrip
1200                     CHECK(json::from_cbor(result) == j);
1201                     CHECK(json::from_cbor(result, true, false) == j);
1202                 }
1203             }
1204         }
1205 
1206         SECTION("array")
1207         {
1208             SECTION("empty")
1209             {
1210                 json j = json::array();
1211                 std::vector<uint8_t> expected = {0x80};
1212                 const auto result = json::to_cbor(j);
1213                 CHECK(result == expected);
1214 
1215                 // roundtrip
1216                 CHECK(json::from_cbor(result) == j);
1217                 CHECK(json::from_cbor(result, true, false) == j);
1218             }
1219 
1220             SECTION("[null]")
1221             {
1222                 json j = {nullptr};
1223                 std::vector<uint8_t> expected = {0x81, 0xf6};
1224                 const auto result = json::to_cbor(j);
1225                 CHECK(result == expected);
1226 
1227                 // roundtrip
1228                 CHECK(json::from_cbor(result) == j);
1229                 CHECK(json::from_cbor(result, true, false) == j);
1230             }
1231 
1232             SECTION("[1,2,3,4,5]")
1233             {
1234                 json j = json::parse("[1,2,3,4,5]");
1235                 std::vector<uint8_t> expected = {0x85, 0x01, 0x02, 0x03, 0x04, 0x05};
1236                 const auto result = json::to_cbor(j);
1237                 CHECK(result == expected);
1238 
1239                 // roundtrip
1240                 CHECK(json::from_cbor(result) == j);
1241                 CHECK(json::from_cbor(result, true, false) == j);
1242             }
1243 
1244             SECTION("[[[[]]]]")
1245             {
1246                 json j = json::parse("[[[[]]]]");
1247                 std::vector<uint8_t> expected = {0x81, 0x81, 0x81, 0x80};
1248                 const auto result = json::to_cbor(j);
1249                 CHECK(result == expected);
1250 
1251                 // roundtrip
1252                 CHECK(json::from_cbor(result) == j);
1253                 CHECK(json::from_cbor(result, true, false) == j);
1254             }
1255 
1256             SECTION("array with uint16_t elements")
1257             {
1258                 json j(257, nullptr);
1259                 std::vector<uint8_t> expected(j.size() + 3, 0xf6); // all null
1260                 expected[0] = 0x99; // array 16 bit
1261                 expected[1] = 0x01; // size (0x0101), byte 0
1262                 expected[2] = 0x01; // size (0x0101), byte 1
1263                 const auto result = json::to_cbor(j);
1264                 CHECK(result == expected);
1265 
1266                 // roundtrip
1267                 CHECK(json::from_cbor(result) == j);
1268                 CHECK(json::from_cbor(result, true, false) == j);
1269             }
1270 
1271             SECTION("array with uint32_t elements")
1272             {
1273                 json j(65793, nullptr);
1274                 std::vector<uint8_t> expected(j.size() + 5, 0xf6); // all null
1275                 expected[0] = 0x9a; // array 32 bit
1276                 expected[1] = 0x00; // size (0x00010101), byte 0
1277                 expected[2] = 0x01; // size (0x00010101), byte 1
1278                 expected[3] = 0x01; // size (0x00010101), byte 2
1279                 expected[4] = 0x01; // size (0x00010101), byte 3
1280                 const auto result = json::to_cbor(j);
1281                 CHECK(result == expected);
1282 
1283                 // roundtrip
1284                 CHECK(json::from_cbor(result) == j);
1285                 CHECK(json::from_cbor(result, true, false) == j);
1286             }
1287         }
1288 
1289         SECTION("object")
1290         {
1291             SECTION("empty")
1292             {
1293                 json j = json::object();
1294                 std::vector<uint8_t> expected = {0xa0};
1295                 const auto result = json::to_cbor(j);
1296                 CHECK(result == expected);
1297 
1298                 // roundtrip
1299                 CHECK(json::from_cbor(result) == j);
1300                 CHECK(json::from_cbor(result, true, false) == j);
1301             }
1302 
1303             SECTION("{\"\":null}")
1304             {
1305                 json j = {{"", nullptr}};
1306                 std::vector<uint8_t> expected = {0xa1, 0x60, 0xf6};
1307                 const auto result = json::to_cbor(j);
1308                 CHECK(result == expected);
1309 
1310                 // roundtrip
1311                 CHECK(json::from_cbor(result) == j);
1312                 CHECK(json::from_cbor(result, true, false) == j);
1313             }
1314 
1315             SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
1316             {
1317                 json j = json::parse(R"({"a": {"b": {"c": {}}}})");
1318                 std::vector<uint8_t> expected =
1319                 {
1320                     0xa1, 0x61, 0x61, 0xa1, 0x61, 0x62, 0xa1, 0x61, 0x63, 0xa0
1321                 };
1322                 const auto result = json::to_cbor(j);
1323                 CHECK(result == expected);
1324 
1325                 // roundtrip
1326                 CHECK(json::from_cbor(result) == j);
1327                 CHECK(json::from_cbor(result, true, false) == j);
1328             }
1329 
1330             SECTION("object with uint8_t elements")
1331             {
1332                 json j;
1333                 for (auto i = 0; i < 255; ++i)
1334                 {
1335                     // format i to a fixed width of 5
1336                     // each entry will need 7 bytes: 6 for string, 1 for null
1337                     std::stringstream ss;
1338                     ss << std::setw(5) << std::setfill('0') << i;
1339                     j.emplace(ss.str(), nullptr);
1340                 }
1341 
1342                 const auto result = json::to_cbor(j);
1343 
1344                 // Checking against an expected vector byte by byte is
1345                 // difficult, because no assumption on the order of key/value
1346                 // pairs are made. We therefore only check the prefix (type and
1347                 // size and the overall size. The rest is then handled in the
1348                 // roundtrip check.
1349                 CHECK(result.size() == 1787); // 1 type, 1 size, 255*7 content
1350                 CHECK(result[0] == 0xb8); // map 8 bit
1351                 CHECK(result[1] == 0xff); // size byte (0xff)
1352                 // roundtrip
1353                 CHECK(json::from_cbor(result) == j);
1354                 CHECK(json::from_cbor(result, true, false) == j);
1355             }
1356 
1357             SECTION("object with uint16_t elements")
1358             {
1359                 json j;
1360                 for (auto i = 0; i < 256; ++i)
1361                 {
1362                     // format i to a fixed width of 5
1363                     // each entry will need 7 bytes: 6 for string, 1 for null
1364                     std::stringstream ss;
1365                     ss << std::setw(5) << std::setfill('0') << i;
1366                     j.emplace(ss.str(), nullptr);
1367                 }
1368 
1369                 const auto result = json::to_cbor(j);
1370 
1371                 // Checking against an expected vector byte by byte is
1372                 // difficult, because no assumption on the order of key/value
1373                 // pairs are made. We therefore only check the prefix (type and
1374                 // size and the overall size. The rest is then handled in the
1375                 // roundtrip check.
1376                 CHECK(result.size() == 1795); // 1 type, 2 size, 256*7 content
1377                 CHECK(result[0] == 0xb9); // map 16 bit
1378                 CHECK(result[1] == 0x01); // byte 0 of size (0x0100)
1379                 CHECK(result[2] == 0x00); // byte 1 of size (0x0100)
1380 
1381                 // roundtrip
1382                 CHECK(json::from_cbor(result) == j);
1383                 CHECK(json::from_cbor(result, true, false) == j);
1384             }
1385 
1386             SECTION("object with uint32_t elements")
1387             {
1388                 json j;
1389                 for (auto i = 0; i < 65536; ++i)
1390                 {
1391                     // format i to a fixed width of 5
1392                     // each entry will need 7 bytes: 6 for string, 1 for null
1393                     std::stringstream ss;
1394                     ss << std::setw(5) << std::setfill('0') << i;
1395                     j.emplace(ss.str(), nullptr);
1396                 }
1397 
1398                 const auto result = json::to_cbor(j);
1399 
1400                 // Checking against an expected vector byte by byte is
1401                 // difficult, because no assumption on the order of key/value
1402                 // pairs are made. We therefore only check the prefix (type and
1403                 // size and the overall size. The rest is then handled in the
1404                 // roundtrip check.
1405                 CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content
1406                 CHECK(result[0] == 0xba); // map 32 bit
1407                 CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)
1408                 CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)
1409                 CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)
1410                 CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)
1411 
1412                 // roundtrip
1413                 CHECK(json::from_cbor(result) == j);
1414                 CHECK(json::from_cbor(result, true, false) == j);
1415             }
1416         }
1417 
1418         SECTION("binary")
1419         {
1420             SECTION("N = 0..23")
1421             {
1422                 for (size_t N = 0; N <= 0x17; ++N)
1423                 {
1424                     CAPTURE(N)
1425 
1426                     // create JSON value with byte array containing of N * 'x'
1427                     const auto s = std::vector<uint8_t>(N, 'x');
1428                     json j = json::binary(s);
1429 
1430                     // create expected byte vector
1431                     std::vector<uint8_t> expected;
1432                     expected.push_back(static_cast<uint8_t>(0x40 + N));
1433                     for (size_t i = 0; i < N; ++i)
1434                     {
1435                         expected.push_back(0x78);
1436                     }
1437 
1438                     // compare result + size
1439                     const auto result = json::to_cbor(j);
1440                     CHECK(result == expected);
1441                     CHECK(result.size() == N + 1);
1442                     // check that no null byte is appended
1443                     if (N > 0)
1444                     {
1445                         CHECK(result.back() != '\x00');
1446                     }
1447 
1448                     // roundtrip
1449                     CHECK(json::from_cbor(result) == j);
1450                     CHECK(json::from_cbor(result, true, false) == j);
1451                 }
1452             }
1453 
1454             SECTION("N = 24..255")
1455             {
1456                 for (size_t N = 24; N <= 255; ++N)
1457                 {
1458                     CAPTURE(N)
1459 
1460                     // create JSON value with string containing of N * 'x'
1461                     const auto s = std::vector<uint8_t>(N, 'x');
1462                     json j = json::binary(s);
1463 
1464                     // create expected byte vector
1465                     std::vector<uint8_t> expected;
1466                     expected.push_back(0x58);
1467                     expected.push_back(static_cast<uint8_t>(N));
1468                     for (size_t i = 0; i < N; ++i)
1469                     {
1470                         expected.push_back('x');
1471                     }
1472 
1473                     // compare result + size
1474                     const auto result = json::to_cbor(j);
1475                     CHECK(result == expected);
1476                     CHECK(result.size() == N + 2);
1477                     // check that no null byte is appended
1478                     CHECK(result.back() != '\x00');
1479 
1480                     // roundtrip
1481                     CHECK(json::from_cbor(result) == j);
1482                     CHECK(json::from_cbor(result, true, false) == j);
1483                 }
1484             }
1485 
1486             SECTION("N = 256..65535")
1487             {
1488                 for (size_t N :
1489                         {
1490                             256u, 999u, 1025u, 3333u, 2048u, 65535u
1491                         })
1492                 {
1493                     CAPTURE(N)
1494 
1495                     // create JSON value with string containing of N * 'x'
1496                     const auto s = std::vector<uint8_t>(N, 'x');
1497                     json j = json::binary(s);
1498 
1499                     // create expected byte vector (hack: create string first)
1500                     std::vector<uint8_t> expected(N, 'x');
1501                     // reverse order of commands, because we insert at begin()
1502                     expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1503                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1504                     expected.insert(expected.begin(), 0x59);
1505 
1506                     // compare result + size
1507                     const auto result = json::to_cbor(j);
1508                     CHECK(result == expected);
1509                     CHECK(result.size() == N + 3);
1510                     // check that no null byte is appended
1511                     CHECK(result.back() != '\x00');
1512 
1513                     // roundtrip
1514                     CHECK(json::from_cbor(result) == j);
1515                     CHECK(json::from_cbor(result, true, false) == j);
1516                 }
1517             }
1518 
1519             SECTION("N = 65536..4294967295")
1520             {
1521                 for (size_t N :
1522                         {
1523                             65536u, 77777u, 1048576u
1524                         })
1525                 {
1526                     CAPTURE(N)
1527 
1528                     // create JSON value with string containing of N * 'x'
1529                     const auto s = std::vector<uint8_t>(N, 'x');
1530                     json j = json::binary(s);
1531 
1532                     // create expected byte vector (hack: create string first)
1533                     std::vector<uint8_t> expected(N, 'x');
1534                     // reverse order of commands, because we insert at begin()
1535                     expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1536                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1537                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
1538                     expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
1539                     expected.insert(expected.begin(), 0x5a);
1540 
1541                     // compare result + size
1542                     const auto result = json::to_cbor(j);
1543                     CHECK(result == expected);
1544                     CHECK(result.size() == N + 5);
1545                     // check that no null byte is appended
1546                     CHECK(result.back() != '\x00');
1547 
1548                     // roundtrip
1549                     CHECK(json::from_cbor(result) == j);
1550                     CHECK(json::from_cbor(result, true, false) == j);
1551                 }
1552             }
1553 
1554             SECTION("indefinite size")
1555             {
1556                 std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};
1557                 auto j = json::from_cbor(input);
1558                 CHECK(j.is_binary());
1559                 auto k = json::binary({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
1560                 CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict))
1561                 CHECK(j == k);
1562             }
1563 
1564             SECTION("binary in array")
1565             {
1566                 // array with three empty byte strings
1567                 std::vector<std::uint8_t> input = {0x83, 0x40, 0x40, 0x40};
1568                 json _;
1569                 CHECK_NOTHROW(_ = json::from_cbor(input));
1570             }
1571 
1572             SECTION("binary in object")
1573             {
1574                 // object mapping "foo" to empty byte string
1575                 std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x40};
1576                 json _;
1577                 CHECK_NOTHROW(_ = json::from_cbor(input));
1578             }
1579 
1580             SECTION("SAX callback with binary")
1581             {
1582                 // object mapping "foo" to byte string
1583                 std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x41, 0x00};
1584 
1585                 // callback to set binary_seen to true if a binary value was seen
1586                 bool binary_seen = false;
1587                 auto callback = [&binary_seen](int /*depth*/, json::parse_event_t /*event*/, json & parsed) noexcept
__anonb6a849290202(int , json::parse_event_t , json & parsed) 1588                 {
1589                     if (parsed.is_binary())
1590                     {
1591                         binary_seen = true;
1592                     }
1593                     return true;
1594                 };
1595 
1596                 json j;
1597                 auto cbp = nlohmann::detail::json_sax_dom_callback_parser<json>(j, callback, true);
1598                 CHECK(json::sax_parse(input, &cbp, json::input_format_t::cbor));
1599                 CHECK(j.at("foo").is_binary());
1600                 CHECK(binary_seen);
1601             }
1602         }
1603     }
1604 
1605     SECTION("additional deserialization")
1606     {
1607         SECTION("0x5b (byte array)")
1608         {
1609             std::vector<uint8_t> given = {0x5b, 0x00, 0x00, 0x00, 0x00,
1610                                           0x00, 0x00, 0x00, 0x01, 0x61
1611                                          };
1612             json j = json::from_cbor(given);
1613             CHECK(j == json::binary(std::vector<uint8_t> {'a'}));
1614         }
1615 
1616         SECTION("0x7b (string)")
1617         {
1618             std::vector<uint8_t> given = {0x7b, 0x00, 0x00, 0x00, 0x00,
1619                                           0x00, 0x00, 0x00, 0x01, 0x61
1620                                          };
1621             json j = json::from_cbor(given);
1622             CHECK(j == "a");
1623         }
1624 
1625         SECTION("0x9b (array)")
1626         {
1627             std::vector<uint8_t> given = {0x9b, 0x00, 0x00, 0x00, 0x00,
1628                                           0x00, 0x00, 0x00, 0x01, 0xf4
1629                                          };
1630             json j = json::from_cbor(given);
1631             CHECK(j == json::parse("[false]"));
1632         }
1633 
1634         SECTION("0xbb (map)")
1635         {
1636             std::vector<uint8_t> given = {0xbb, 0x00, 0x00, 0x00, 0x00,
1637                                           0x00, 0x00, 0x00, 0x01, 0x60, 0xf4
1638                                          };
1639             json j = json::from_cbor(given);
1640             CHECK(j == json::parse("{\"\": false}"));
1641         }
1642     }
1643 
1644     SECTION("errors")
1645     {
1646         SECTION("empty byte vector")
1647         {
1648             json _;
1649             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>()), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1650             CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded());
1651         }
1652 
1653         SECTION("too short byte vector")
1654         {
1655             json _;
1656             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x18})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1657             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1658             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1659             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1660             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1661             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1662             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1663             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1664             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1665             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1666             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1667             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1668             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1669             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1670             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1671             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1672             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62, 0x60})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1673             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1674             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1675             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x82, 0x01})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1676             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1677             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1678             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0X61})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1679             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1680             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input", json::parse_error&);
1681             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F, 0x00})), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR binary: expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x00", json::parse_error&);
1682             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x41})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input", json::parse_error&);
1683 
1684             CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded());
1685             CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded());
1686             CHECK(json::from_cbor(std::vector<uint8_t>({0x19, 0x00}), true, false).is_discarded());
1687             CHECK(json::from_cbor(std::vector<uint8_t>({0x1a}), true, false).is_discarded());
1688             CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00}), true, false).is_discarded());
1689             CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00}), true, false).is_discarded());
1690             CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00}), true, false).is_discarded());
1691             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b}), true, false).is_discarded());
1692             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00}), true, false).is_discarded());
1693             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00}), true, false).is_discarded());
1694             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00}), true, false).is_discarded());
1695             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1696             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1697             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1698             CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1699             CHECK(json::from_cbor(std::vector<uint8_t>({0x62}), true, false).is_discarded());
1700             CHECK(json::from_cbor(std::vector<uint8_t>({0x62, 0x60}), true, false).is_discarded());
1701             CHECK(json::from_cbor(std::vector<uint8_t>({0x7F}), true, false).is_discarded());
1702             CHECK(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60}), true, false).is_discarded());
1703             CHECK(json::from_cbor(std::vector<uint8_t>({0x82, 0x01}), true, false).is_discarded());
1704             CHECK(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01}), true, false).is_discarded());
1705             CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5}), true, false).is_discarded());
1706             CHECK(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61}), true, false).is_discarded());
1707             CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61}), true, false).is_discarded());
1708             CHECK(json::from_cbor(std::vector<uint8_t>({0x5F}), true, false).is_discarded());
1709             CHECK(json::from_cbor(std::vector<uint8_t>({0x5F, 0x00}), true, false).is_discarded());
1710             CHECK(json::from_cbor(std::vector<uint8_t>({0x41}), true, false).is_discarded());
1711         }
1712 
1713         SECTION("unsupported bytes")
1714         {
1715             SECTION("concrete examples")
1716             {
1717                 json _;
1718                 CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1c})), "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C", json::parse_error&);
1719                 CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded());
1720 
1721                 CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf8})), "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xF8", json::parse_error&);
1722                 CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded());
1723             }
1724 
1725             SECTION("all unsupported bytes")
1726             {
1727                 for (auto byte :
1728                         {
1729                             // ?
1730                             0x1c, 0x1d, 0x1e, 0x1f,
1731                             // ?
1732                             0x3c, 0x3d, 0x3e, 0x3f,
1733                             // ?
1734                             0x5c, 0x5d, 0x5e,
1735                             // ?
1736                             0x7c, 0x7d, 0x7e,
1737                             // ?
1738                             0x9c, 0x9d, 0x9e,
1739                             // ?
1740                             0xbc, 0xbd, 0xbe,
1741                             // date/time
1742                             0xc0, 0xc1,
1743                             // bignum
1744                             0xc2, 0xc3,
1745                             // fraction
1746                             0xc4,
1747                             // bigfloat
1748                             0xc5,
1749                             // tagged item
1750                             0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
1751                             // expected conversion
1752                             0xd5, 0xd6, 0xd7,
1753                             // more tagged items
1754                             0xd8, 0xd9, 0xda, 0xdb,
1755                             // ?
1756                             0xdc, 0xdd, 0xde, 0xdf,
1757                             // (simple value)
1758                             0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
1759                             // undefined
1760                             0xf7,
1761                             // simple value
1762                             0xf8
1763                         })
1764                 {
1765                     json _;
1766                     CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error&);
1767                     CHECK(json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)}), true, false).is_discarded());
1768                 }
1769             }
1770         }
1771 
1772         SECTION("invalid string in map")
1773         {
1774             json _;
1775             CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF", json::parse_error&);
1776             CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded());
1777         }
1778 
1779         SECTION("strict mode")
1780         {
1781             std::vector<uint8_t> vec = {0xf6, 0xf6};
1782             SECTION("non-strict mode")
1783             {
1784                 const auto result = json::from_cbor(vec, false);
1785                 CHECK(result == json());
1786                 CHECK(!json::from_cbor(vec, false, false).is_discarded());
1787             }
1788 
1789             SECTION("strict mode")
1790             {
1791                 json _;
1792                 CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: expected end of input; last byte: 0xF6", json::parse_error&);
1793                 CHECK(json::from_cbor(vec, true, false).is_discarded());
1794             }
1795         }
1796     }
1797 
1798     SECTION("SAX aborts")
1799     {
1800         SECTION("start_array(len)")
1801         {
1802             std::vector<uint8_t> v = {0x83, 0x01, 0x02, 0x03};
1803             SaxCountdown scp(0);
1804             CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1805         }
1806 
1807         SECTION("start_object(len)")
1808         {
1809             std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};
1810             SaxCountdown scp(0);
1811             CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1812         }
1813 
1814         SECTION("key()")
1815         {
1816             std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};
1817             SaxCountdown scp(1);
1818             CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1819         }
1820     }
1821 }
1822 
1823 // use this testcase outside [hide] to run it with Valgrind
1824 TEST_CASE("single CBOR roundtrip")
1825 {
1826     SECTION("sample.json")
1827     {
1828         std::string filename = TEST_DATA_DIRECTORY "/json_testsuite/sample.json";
1829 
1830         // parse JSON file
1831         std::ifstream f_json(filename);
1832         json j1 = json::parse(f_json);
1833 
1834         // parse CBOR file
1835         auto packed = utils::read_binary_file(filename + ".cbor");
1836         json j2;
1837         CHECK_NOTHROW(j2 = json::from_cbor(packed));
1838 
1839         // compare parsed JSON values
1840         CHECK(j1 == j2);
1841 
1842         SECTION("roundtrips")
1843         {
1844             SECTION("std::ostringstream")
1845             {
1846                 std::basic_ostringstream<std::uint8_t> ss;
1847                 json::to_cbor(j1, ss);
1848                 json j3 = json::from_cbor(ss.str());
1849                 CHECK(j1 == j3);
1850             }
1851 
1852             SECTION("std::string")
1853             {
1854                 std::string s;
1855                 json::to_cbor(j1, s);
1856                 json j3 = json::from_cbor(s);
1857                 CHECK(j1 == j3);
1858             }
1859         }
1860 
1861         // check with different start index
1862         packed.insert(packed.begin(), 5, 0xff);
1863         CHECK(j1 == json::from_cbor(packed.begin() + 5, packed.end()));
1864     }
1865 }
1866 
1867 #if !defined(JSON_NOEXCEPTION)
1868 TEST_CASE("CBOR regressions")
1869 {
1870     SECTION("fuzz test results")
1871     {
1872         /*
1873         The following test cases were found during a two-day session with
1874         AFL-Fuzz. As a result, empty byte vectors and excessive lengths are
1875         detected.
1876         */
1877         for (std::string filename :
1878                 {
1879                     TEST_DATA_DIRECTORY "/cbor_regression/test01",
1880                     TEST_DATA_DIRECTORY "/cbor_regression/test02",
1881                     TEST_DATA_DIRECTORY "/cbor_regression/test03",
1882                     TEST_DATA_DIRECTORY "/cbor_regression/test04",
1883                     TEST_DATA_DIRECTORY "/cbor_regression/test05",
1884                     TEST_DATA_DIRECTORY "/cbor_regression/test06",
1885                     TEST_DATA_DIRECTORY "/cbor_regression/test07",
1886                     TEST_DATA_DIRECTORY "/cbor_regression/test08",
1887                     TEST_DATA_DIRECTORY "/cbor_regression/test09",
1888                     TEST_DATA_DIRECTORY "/cbor_regression/test10",
1889                     TEST_DATA_DIRECTORY "/cbor_regression/test11",
1890                     TEST_DATA_DIRECTORY "/cbor_regression/test12",
1891                     TEST_DATA_DIRECTORY "/cbor_regression/test13",
1892                     TEST_DATA_DIRECTORY "/cbor_regression/test14",
1893                     TEST_DATA_DIRECTORY "/cbor_regression/test15",
1894                     TEST_DATA_DIRECTORY "/cbor_regression/test16",
1895                     TEST_DATA_DIRECTORY "/cbor_regression/test17",
1896                     TEST_DATA_DIRECTORY "/cbor_regression/test18",
1897                     TEST_DATA_DIRECTORY "/cbor_regression/test19",
1898                     TEST_DATA_DIRECTORY "/cbor_regression/test20",
1899                     TEST_DATA_DIRECTORY "/cbor_regression/test21"
1900                 })
1901         {
CAPTURE(filename)1902             CAPTURE(filename)
1903 
1904             try
1905             {
1906                 // parse CBOR file
1907                 auto vec1 = utils::read_binary_file(filename);
1908                 json j1 = json::from_cbor(vec1);
1909 
1910                 try
1911                 {
1912                     // step 2: round trip
1913                     std::vector<uint8_t> vec2 = json::to_cbor(j1);
1914 
1915                     // parse serialization
1916                     json j2 = json::from_cbor(vec2);
1917 
1918                     // deserializations must match
1919                     CHECK(j1 == j2);
1920                 }
1921                 catch (const json::parse_error&)
1922                 {
1923                     // parsing a CBOR serialization must not fail
1924                     CHECK(false);
1925                 }
1926             }
1927             catch (const json::parse_error&)
1928             {
1929                 // parse errors are ok, because input may be random bytes
1930             }
1931         }
1932     }
1933 }
1934 #endif
1935 
skip()1936 TEST_CASE("CBOR roundtrips" * doctest::skip())
1937 {
1938     SECTION("input from flynn")
1939     {
1940         // most of these are excluded due to differences in key order (not a real problem)
1941         std::set<std::string> exclude_packed;
1942         exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/1.json");
1943         exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/2.json");
1944         exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/3.json");
1945         exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/4.json");
1946         exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/5.json");
1947         exclude_packed.insert(TEST_DATA_DIRECTORY "/json_testsuite/sample.json"); // kills AppVeyor
1948         exclude_packed.insert(TEST_DATA_DIRECTORY "/json_tests/pass1.json");
1949         exclude_packed.insert(TEST_DATA_DIRECTORY "/regression/working_file.json");
1950         exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json");
1951         exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json");
1952         exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json");
1953 
1954         for (std::string filename :
1955                 {
1956                     TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
1957                     TEST_DATA_DIRECTORY "/json.org/1.json",
1958                     TEST_DATA_DIRECTORY "/json.org/2.json",
1959                     TEST_DATA_DIRECTORY "/json.org/3.json",
1960                     TEST_DATA_DIRECTORY "/json.org/4.json",
1961                     TEST_DATA_DIRECTORY "/json.org/5.json",
1962                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
1963                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
1964                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
1965                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
1966                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
1967                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
1968                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
1969                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
1970                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
1971                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
1972                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
1973                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
1974                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
1975                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
1976                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
1977                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
1978                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
1979                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
1980                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
1981                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
1982                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
1983                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
1984                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
1985                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
1986                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
1987                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
1988                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
1989                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
1990                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
1991                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
1992                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
1993                     TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
1994                     TEST_DATA_DIRECTORY "/json_testsuite/sample.json", // kills AppVeyor
1995                     TEST_DATA_DIRECTORY "/json_tests/pass1.json",
1996                     TEST_DATA_DIRECTORY "/json_tests/pass2.json",
1997                     TEST_DATA_DIRECTORY "/json_tests/pass3.json",
1998                     TEST_DATA_DIRECTORY "/regression/floats.json",
1999                     TEST_DATA_DIRECTORY "/regression/signed_ints.json",
2000                     TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
2001                     TEST_DATA_DIRECTORY "/regression/working_file.json",
2002                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json",
2003                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty-string.json",
2004                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty.json",
2005                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json",
2006                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_false.json",
2007                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_heterogeneous.json",
2008                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_null.json",
2009                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json",
2010                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_leading_space.json",
2011                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_several_null.json",
2012                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json",
2013                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number.json",
2014                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e+1.json",
2015                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e1.json",
2016                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_after_space.json",
2017                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
2018                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
2019                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
2020                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
2021                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
2022                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_int.json",
2023                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_one.json",
2024                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_zero.json",
2025                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e.json",
2026                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json",
2027                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json",
2028                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
2029                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
2030                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
2031                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
2032                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
2033                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
2034                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
2035                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_int.json",
2036                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_real.json",
2037                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json",
2038                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json",
2039                     //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json",
2040                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json",
2041                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_basic.json",
2042                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json",
2043                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json",
2044                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty.json",
2045                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty_key.json",
2046                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json",
2047                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json",
2048                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json",
2049                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json",
2050                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json",
2051                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_with_newlines.json",
2052                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
2053                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json",
2054                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json",
2055                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json",
2056                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json",
2057                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json",
2058                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json",
2059                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_comments.json",
2060                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_a.json",
2061                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_n.json",
2062                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json",
2063                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json",
2064                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array.json",
2065                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json",
2066                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json",
2067                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json",
2068                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json",
2069                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json",
2070                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json",
2071                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_null_escape.json",
2072                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json",
2073                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_pi.json",
2074                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_simple_ascii.json",
2075                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_space.json",
2076                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json",
2077                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json",
2078                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json",
2079                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json",
2080                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_uEscape.json",
2081                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json",
2082                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode.json",
2083                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json",
2084                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_2.json",
2085                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json",
2086                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json",
2087                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json",
2088                     // TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf16.json",
2089                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf8.json",
2090                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_with_del_character.json",
2091                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_false.json",
2092                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_int.json",
2093                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json",
2094                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_null.json",
2095                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_string.json",
2096                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_true.json",
2097                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
2098                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
2099                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
2100                     TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"
2101                 })
2102         {
2103             CAPTURE(filename)
2104 
2105             {
2106                 INFO_WITH_TEMP(filename + ": std::vector<uint8_t>");
2107                 // parse JSON file
2108                 std::ifstream f_json(filename);
2109                 json j1 = json::parse(f_json);
2110 
2111                 // parse CBOR file
2112                 auto packed = utils::read_binary_file(filename + ".cbor");
2113                 json j2;
2114                 CHECK_NOTHROW(j2 = json::from_cbor(packed));
2115 
2116                 // compare parsed JSON values
2117                 CHECK(j1 == j2);
2118             }
2119 
2120             {
2121                 INFO_WITH_TEMP(filename + ": std::ifstream");
2122                 // parse JSON file
2123                 std::ifstream f_json(filename);
2124                 json j1 = json::parse(f_json);
2125 
2126                 // parse CBOR file
2127                 std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
2128                 json j2;
2129                 CHECK_NOTHROW(j2 = json::from_cbor(f_cbor));
2130 
2131                 // compare parsed JSON values
2132                 CHECK(j1 == j2);
2133             }
2134 
2135             {
2136                 INFO_WITH_TEMP(filename + ": uint8_t* and size");
2137                 // parse JSON file
2138                 std::ifstream f_json(filename);
2139                 json j1 = json::parse(f_json);
2140 
2141                 // parse CBOR file
2142                 auto packed = utils::read_binary_file(filename + ".cbor");
2143                 json j2;
2144                 CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
2145 
2146                 // compare parsed JSON values
2147                 CHECK(j1 == j2);
2148             }
2149 
2150             {
2151                 INFO_WITH_TEMP(filename + ": output to output adapters");
2152                 // parse JSON file
2153                 std::ifstream f_json(filename);
2154                 json j1 = json::parse(f_json);
2155 
2156                 // parse CBOR file
2157                 auto packed = utils::read_binary_file(filename + ".cbor");
2158 
2159                 if (exclude_packed.count(filename) == 0u)
2160                 {
2161                     {
2162                         INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
2163                         std::vector<uint8_t> vec;
2164                         json::to_cbor(j1, vec);
2165                         CHECK(vec == packed);
2166                     }
2167                 }
2168             }
2169         }
2170     }
2171 }
2172 
2173 #if !defined(JSON_NOEXCEPTION)
2174 TEST_CASE("all CBOR first bytes")
2175 {
2176     // these bytes will fail immediately with exception parse_error.112
2177     std::set<uint8_t> unsupported =
2178     {
2179         //// types not supported by this library
2180 
2181         // date/time
2182         0xc0, 0xc1,
2183         // bignum
2184         0xc2, 0xc3,
2185         // decimal fracion
2186         0xc4,
2187         // bigfloat
2188         0xc5,
2189         // tagged item
2190         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
2191         0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd8,
2192         0xd9, 0xda, 0xdb,
2193         // expected conversion
2194         0xd5, 0xd6, 0xd7,
2195         // simple value
2196         0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
2197         0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xef, 0xf0,
2198         0xf1, 0xf2, 0xf3,
2199         0xf8,
2200         // undefined
2201         0xf7,
2202 
2203         //// bytes not specified by CBOR
2204 
2205         0x1c, 0x1d, 0x1e, 0x1f,
2206         0x3c, 0x3d, 0x3e, 0x3f,
2207         0x5c, 0x5d, 0x5e,
2208         0x7c, 0x7d, 0x7e,
2209         0x9c, 0x9d, 0x9e,
2210         0xbc, 0xbd, 0xbe,
2211         0xdc, 0xdd, 0xde, 0xdf,
2212         0xee,
2213         0xfc, 0xfe, 0xfd,
2214 
2215         /// break cannot be the first byte
2216 
2217         0xff
2218     };
2219 
2220     for (auto i = 0; i < 256; ++i)
2221     {
2222         const auto byte = static_cast<uint8_t>(i);
2223 
2224         try
2225         {
2226             auto res = json::from_cbor(std::vector<uint8_t>(1, byte));
2227         }
2228         catch (const json::parse_error& e)
2229         {
2230             // check that parse_error.112 is only thrown if the
2231             // first byte is in the unsupported set
2232             INFO_WITH_TEMP(e.what());
2233             if (unsupported.find(byte) != unsupported.end())
2234             {
2235                 CHECK(e.id == 112);
2236             }
2237             else
2238             {
2239                 CHECK(e.id != 112);
2240             }
2241         }
2242     }
2243 }
2244 #endif
2245 
2246 TEST_CASE("examples from RFC 7049 Appendix A")
2247 {
2248     SECTION("numbers")
2249     {
2250         CHECK(json::to_cbor(json::parse("0")) == std::vector<uint8_t>({0x00}));
2251         CHECK(json::parse("0") == json::from_cbor(std::vector<uint8_t>({0x00})));
2252 
2253         CHECK(json::to_cbor(json::parse("1")) == std::vector<uint8_t>({0x01}));
2254         CHECK(json::parse("1") == json::from_cbor(std::vector<uint8_t>({0x01})));
2255 
2256         CHECK(json::to_cbor(json::parse("10")) == std::vector<uint8_t>({0x0a}));
2257         CHECK(json::parse("10") == json::from_cbor(std::vector<uint8_t>({0x0a})));
2258 
2259         CHECK(json::to_cbor(json::parse("23")) == std::vector<uint8_t>({0x17}));
2260         CHECK(json::parse("23") == json::from_cbor(std::vector<uint8_t>({0x17})));
2261 
2262         CHECK(json::to_cbor(json::parse("24")) == std::vector<uint8_t>({0x18, 0x18}));
2263         CHECK(json::parse("24") == json::from_cbor(std::vector<uint8_t>({0x18, 0x18})));
2264 
2265         CHECK(json::to_cbor(json::parse("25")) == std::vector<uint8_t>({0x18, 0x19}));
2266         CHECK(json::parse("25") == json::from_cbor(std::vector<uint8_t>({0x18, 0x19})));
2267 
2268         CHECK(json::to_cbor(json::parse("100")) == std::vector<uint8_t>({0x18, 0x64}));
2269         CHECK(json::parse("100") == json::from_cbor(std::vector<uint8_t>({0x18, 0x64})));
2270 
2271         CHECK(json::to_cbor(json::parse("1000")) == std::vector<uint8_t>({0x19, 0x03, 0xe8}));
2272         CHECK(json::parse("1000") == json::from_cbor(std::vector<uint8_t>({0x19, 0x03, 0xe8})));
2273 
2274         CHECK(json::to_cbor(json::parse("1000000")) == std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40}));
2275         CHECK(json::parse("1000000") == json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40})));
2276 
2277         CHECK(json::to_cbor(json::parse("1000000000000")) == std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00}));
2278         CHECK(json::parse("1000000000000") == json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00})));
2279 
2280         CHECK(json::to_cbor(json::parse("18446744073709551615")) == std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));
2281         CHECK(json::parse("18446744073709551615") == json::from_cbor(std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));
2282 
2283         // positive bignum is not supported
2284         //CHECK(json::to_cbor(json::parse("18446744073709551616")) == std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
2285         //CHECK(json::parse("18446744073709551616") == json::from_cbor(std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));
2286 
2287         //CHECK(json::to_cbor(json::parse("-18446744073709551616")) == std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));
2288         //CHECK(json::parse("-18446744073709551616") == json::from_cbor(std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));
2289 
2290         // negative bignum is not supported
2291         //CHECK(json::to_cbor(json::parse("-18446744073709551617")) == std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
2292         //CHECK(json::parse("-18446744073709551617") == json::from_cbor(std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));
2293 
2294         CHECK(json::to_cbor(json::parse("-1")) == std::vector<uint8_t>({0x20}));
2295         CHECK(json::parse("-1") == json::from_cbor(std::vector<uint8_t>({0x20})));
2296 
2297         CHECK(json::to_cbor(json::parse("-10")) == std::vector<uint8_t>({0x29}));
2298         CHECK(json::parse("-10") == json::from_cbor(std::vector<uint8_t>({0x29})));
2299 
2300         CHECK(json::to_cbor(json::parse("-100")) == std::vector<uint8_t>({0x38, 0x63}));
2301         CHECK(json::parse("-100") == json::from_cbor(std::vector<uint8_t>({0x38, 0x63})));
2302 
2303         CHECK(json::to_cbor(json::parse("-1000")) == std::vector<uint8_t>({0x39, 0x03, 0xe7}));
2304         CHECK(json::parse("-1000") == json::from_cbor(std::vector<uint8_t>({0x39, 0x03, 0xe7})));
2305 
2306         // half-precision float
2307         //CHECK(json::to_cbor(json::parse("0.0")) == std::vector<uint8_t>({0xf9, 0x00, 0x00}));
2308         CHECK(json::parse("0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00})));
2309 
2310         // half-precision float
2311         //CHECK(json::to_cbor(json::parse("-0.0")) == std::vector<uint8_t>({0xf9, 0x80, 0x00}));
2312         CHECK(json::parse("-0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00})));
2313 
2314         // half-precision float
2315         //CHECK(json::to_cbor(json::parse("1.0")) == std::vector<uint8_t>({0xf9, 0x3c, 0x00}));
2316         CHECK(json::parse("1.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00})));
2317 
2318         CHECK(json::to_cbor(json::parse("1.1")) == std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}));
2319         CHECK(json::parse("1.1") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a})));
2320 
2321         // half-precision float
2322         //CHECK(json::to_cbor(json::parse("1.5")) == std::vector<uint8_t>({0xf9, 0x3e, 0x00}));
2323         CHECK(json::parse("1.5") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3e, 0x00})));
2324 
2325         // half-precision float
2326         //CHECK(json::to_cbor(json::parse("65504.0")) == std::vector<uint8_t>({0xf9, 0x7b, 0xff}));
2327         CHECK(json::parse("65504.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff})));
2328 
2329         //CHECK(json::to_cbor(json::parse("100000.0")) == std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00}));
2330         CHECK(json::parse("100000.0") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00})));
2331 
2332         //CHECK(json::to_cbor(json::parse("3.4028234663852886e+38")) == std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff}));
2333         CHECK(json::parse("3.4028234663852886e+38") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff})));
2334 
2335         CHECK(json::to_cbor(json::parse("1.0e+300")) == std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c}));
2336         CHECK(json::parse("1.0e+300") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c})));
2337 
2338         // half-precision float
2339         //CHECK(json::to_cbor(json::parse("5.960464477539063e-8")) == std::vector<uint8_t>({0xf9, 0x00, 0x01}));
2340         CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2341 
2342         // half-precision float
2343         //CHECK(json::to_cbor(json::parse("0.00006103515625")) == std::vector<uint8_t>({0xf9, 0x04, 0x00}));
2344         CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2345 
2346         // half-precision float
2347         //CHECK(json::to_cbor(json::parse("-4.0")) == std::vector<uint8_t>({0xf9, 0xc4, 0x00}));
2348         CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2349 
2350         CHECK(json::to_cbor(json::parse("-4.1")) == std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}));
2351         CHECK(json::parse("-4.1") == json::from_cbor(std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})));
2352     }
2353 
2354     SECTION("simple values")
2355     {
2356         CHECK(json::to_cbor(json::parse("false")) == std::vector<uint8_t>({0xf4}));
2357         CHECK(json::parse("false") == json::from_cbor(std::vector<uint8_t>({0xf4})));
2358 
2359         CHECK(json::to_cbor(json::parse("true")) == std::vector<uint8_t>({0xf5}));
2360         CHECK(json::parse("true") == json::from_cbor(std::vector<uint8_t>({0xf5})));
2361 
2362         CHECK(json::to_cbor(json::parse("true")) == std::vector<uint8_t>({0xf5}));
2363         CHECK(json::parse("true") == json::from_cbor(std::vector<uint8_t>({0xf5})));
2364     }
2365 
2366     SECTION("strings")
2367     {
2368         CHECK(json::to_cbor(json::parse("\"\"")) == std::vector<uint8_t>({0x60}));
2369         CHECK(json::parse("\"\"") == json::from_cbor(std::vector<uint8_t>({0x60})));
2370 
2371         CHECK(json::to_cbor(json::parse("\"a\"")) == std::vector<uint8_t>({0x61, 0x61}));
2372         CHECK(json::parse("\"a\"") == json::from_cbor(std::vector<uint8_t>({0x61, 0x61})));
2373 
2374         CHECK(json::to_cbor(json::parse("\"IETF\"")) == std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46}));
2375         CHECK(json::parse("\"IETF\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46})));
2376 
2377         CHECK(json::to_cbor(json::parse("\"\\u00fc\"")) == std::vector<uint8_t>({0x62, 0xc3, 0xbc}));
2378         CHECK(json::parse("\"\\u00fc\"") == json::from_cbor(std::vector<uint8_t>({0x62, 0xc3, 0xbc})));
2379 
2380         CHECK(json::to_cbor(json::parse("\"\\u6c34\"")) == std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4}));
2381         CHECK(json::parse("\"\\u6c34\"") == json::from_cbor(std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4})));
2382 
2383         CHECK(json::to_cbor(json::parse("\"\\ud800\\udd51\"")) == std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91}));
2384         CHECK(json::parse("\"\\ud800\\udd51\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91})));
2385 
2386         // indefinite length strings
2387         CHECK(json::parse("\"streaming\"") == json::from_cbor(std::vector<uint8_t>({0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff})));
2388     }
2389 
2390     SECTION("byte arrays")
2391     {
2392         auto packed = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor");
2393         json j;
2394         CHECK_NOTHROW(j = json::from_cbor(packed));
2395 
2396         auto expected = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out");
2397         CHECK(j == json::binary(expected));
2398 
2399         // 0xd8
2400         CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});
2401         CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2402         CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 0x42);
2403         // 0xd9
2404         CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)) == std::vector<uint8_t> {0xd9, 0x03, 0xe8, 0x40});
2405         CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2406         CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 1000);
2407         // 0xda
2408         CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)) == std::vector<uint8_t> {0xda, 0x00, 0x06, 0x03, 0xe8, 0x40});
2409         CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2410         CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 394216);
2411         // 0xdb
2412         CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)) == std::vector<uint8_t> {0xdb, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x40});
2413         CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2414         CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 8589934590);
2415     }
2416 
2417     SECTION("arrays")
2418     {
2419         CHECK(json::to_cbor(json::parse("[]")) == std::vector<uint8_t>({0x80}));
2420         CHECK(json::parse("[]") == json::from_cbor(std::vector<uint8_t>({0x80})));
2421 
2422         CHECK(json::to_cbor(json::parse("[1, 2, 3]")) == std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03}));
2423         CHECK(json::parse("[1, 2, 3]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03})));
2424 
2425         CHECK(json::to_cbor(json::parse("[1, [2, 3], [4, 5]]")) == std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05}));
2426         CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05})));
2427 
2428         CHECK(json::to_cbor(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]")) == std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19}));
2429         CHECK(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]") == json::from_cbor(std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19})));
2430 
2431         // indefinite length arrays
2432         CHECK(json::parse("[]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0xff})));
2433         CHECK(json::parse("[1, [2, 3], [4, 5]] ") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff, 0xff})));
2434         CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05, 0xff})));
2435         CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff})));
2436         CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x9f, 0x02, 0x03, 0xff, 0x82, 0x04, 0x05})));
2437         CHECK(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0xff})));
2438     }
2439 
2440     SECTION("objects")
2441     {
2442         CHECK(json::to_cbor(json::parse("{}")) == std::vector<uint8_t>({0xa0}));
2443         CHECK(json::parse("{}") == json::from_cbor(std::vector<uint8_t>({0xa0})));
2444 
2445         CHECK(json::to_cbor(json::parse("{\"a\": 1, \"b\": [2, 3]}")) == std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03}));
2446         CHECK(json::parse("{\"a\": 1, \"b\": [2, 3]}") == json::from_cbor(std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03})));
2447 
2448         CHECK(json::to_cbor(json::parse("[\"a\", {\"b\": \"c\"}]")) == std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63}));
2449         CHECK(json::parse("[\"a\", {\"b\": \"c\"}]") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63})));
2450 
2451         CHECK(json::to_cbor(json::parse("{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\", \"e\": \"E\"}")) == std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45}));
2452         CHECK(json::parse("{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\", \"e\": \"E\"}") == json::from_cbor(std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45})));
2453 
2454         // indefinite length objects
2455         CHECK(json::parse("{\"a\": 1, \"b\": [2, 3]}") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x61, 0x61, 0x01, 0x61, 0x62, 0x9f, 0x02, 0x03, 0xff, 0xff})));
2456         CHECK(json::parse("[\"a\", {\"b\": \"c\"}]") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xbf, 0x61, 0x62, 0x61, 0x63, 0xff})));
2457         CHECK(json::parse("{\"Fun\": true, \"Amt\": -2}") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x63, 0x46, 0x75, 0x6e, 0xf5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xff})));
2458     }
2459 }
2460 
2461 TEST_CASE("Tagged values")
2462 {
2463     json j = "s";
2464     auto v = json::to_cbor(j);
2465 
2466     SECTION("0xC6..0xD4")
2467     {
2468         for (auto b : std::vector<std::uint8_t>
2469     {
2470         0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4
2471     })
2472         {
2473             CAPTURE(b);
2474 
2475             // add tag to value
2476             auto v_tagged = v;
2477             v_tagged.insert(v_tagged.begin(), b);
2478 
2479             // check that parsing fails in error mode
2480             json _;
2481             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2482             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2483 
2484             // check that parsing succeeds and gets original value in ignore mode
2485             auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2486             CHECK(j_tagged == j);
2487 
2488             auto j_tagged_stored = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::store);
2489             CHECK(j_tagged_stored == j);
2490         }
2491     }
2492 
2493     SECTION("0xD8 - 1 byte follows")
2494     {
2495         SECTION("success")
2496         {
2497             // add tag to value
2498             auto v_tagged = v;
2499             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2500             v_tagged.insert(v_tagged.begin(), 0xD8); // tag
2501 
2502             // check that parsing fails in error mode
2503             json _;
2504             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2505             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2506 
2507             // check that parsing succeeds and gets original value in ignore mode
2508             auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2509             CHECK(j_tagged == j);
2510         }
2511 
2512         SECTION("missing byte after tag")
2513         {
2514             // add tag to value
2515             auto v_tagged = v;
2516             v_tagged.insert(v_tagged.begin(), 0xD8); // tag
2517 
2518             // check that parsing fails in all modes
2519             json _;
2520             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2521             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2522             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2523         }
2524     }
2525 
2526     SECTION("0xD9 - 2 byte follow")
2527     {
2528         SECTION("success")
2529         {
2530             // add tag to value
2531             auto v_tagged = v;
2532             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2533             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2534             v_tagged.insert(v_tagged.begin(), 0xD9); // tag
2535 
2536             // check that parsing fails in error mode
2537             json _;
2538             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2539             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2540 
2541             // check that parsing succeeds and gets original value in ignore mode
2542             auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2543             CHECK(j_tagged == j);
2544         }
2545 
2546         SECTION("missing byte after tag")
2547         {
2548             // add tag to value
2549             auto v_tagged = v;
2550             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2551             v_tagged.insert(v_tagged.begin(), 0xD9); // tag
2552 
2553             // check that parsing fails in all modes
2554             json _;
2555             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2556             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2557             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2558         }
2559     }
2560 
2561     SECTION("0xDA - 4 bytes follow")
2562     {
2563         SECTION("success")
2564         {
2565             // add tag to value
2566             auto v_tagged = v;
2567             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2568             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2569             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2570             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2571             v_tagged.insert(v_tagged.begin(), 0xDA); // tag
2572 
2573             // check that parsing fails in error mode
2574             json _;
2575             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2576             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2577 
2578             // check that parsing succeeds and gets original value in ignore mode
2579             auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2580             CHECK(j_tagged == j);
2581         }
2582 
2583         SECTION("missing bytes after tag")
2584         {
2585             // add tag to value
2586             auto v_tagged = v;
2587             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2588             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2589             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2590             v_tagged.insert(v_tagged.begin(), 0xDA); // tag
2591 
2592             // check that parsing fails in all modes
2593             json _;
2594             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2595             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2596             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2597         }
2598     }
2599 
2600     SECTION("0xDB - 8 bytes follow")
2601     {
2602         SECTION("success")
2603         {
2604             // add tag to value
2605             auto v_tagged = v;
2606             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2607             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2608             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2609             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2610             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2611             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2612             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2613             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2614             v_tagged.insert(v_tagged.begin(), 0xDB); // tag
2615 
2616             // check that parsing fails in error mode
2617             json _;
2618             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2619             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2620 
2621             // check that parsing succeeds and gets original value in ignore mode
2622             auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2623             CHECK(j_tagged == j);
2624         }
2625 
2626         SECTION("missing byte after tag")
2627         {
2628             // add tag to value
2629             auto v_tagged = v;
2630             v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2631             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2632             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2633             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2634             v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2635             v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2636             v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2637             v_tagged.insert(v_tagged.begin(), 0xDB); // tag
2638 
2639             // check that parsing fails in all modes
2640             json _;
2641             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2642             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2643             CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2644         }
2645     }
2646 
2647     SECTION("tagged binary")
2648     {
2649         // create a binary value of subtype 42
2650         json j_binary;
2651         j_binary["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
2652 
2653         // convert to CBOR
2654         const auto vec = json::to_cbor(j_binary);
2655         CHECK(vec == std::vector<std::uint8_t> {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE});
2656 
2657         // parse error when parsing tagged value
2658         json _;
2659         CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8", json::parse_error);
2660 
2661         // binary without subtype when tags are ignored
2662         json jb = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);
2663         CHECK(jb.is_object());
2664         CHECK(jb["binary"].is_binary());
2665         CHECK(!jb["binary"].get_binary().has_subtype());
2666     }
2667 }
2668