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