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