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