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