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