1 /* 2 __ _____ _____ _____ 3 __| | __| | | | JSON for Modern C++ (test suite) 4 | | |__ | | | | | | version 3.9.1 5 |_____|_____|_____|_|___| https://github.com/nlohmann/json 6 7 Licensed under the MIT License <http://opensource.org/licenses/MIT>. 8 SPDX-License-Identifier: MIT 9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>. 10 11 Permission is hereby granted, free of charge, to any person obtaining a copy 12 of this software and associated documentation files (the "Software"), to deal 13 in the Software without restriction, including without limitation the rights 14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 copies of the Software, and to permit persons to whom the Software is 16 furnished to do so, subject to the following conditions: 17 18 The above copyright notice and this permission notice shall be included in all 19 copies or substantial portions of the Software. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 SOFTWARE. 28 */ 29 30 #include "doctest_compatibility.h" 31 32 #include <nlohmann/json.hpp> 33 using nlohmann::json; 34 35 #include <iostream> 36 #include <sstream> 37 #include <valarray> 38 39 namespace 40 { 41 struct SaxEventLogger : public nlohmann::json_sax<json> 42 { null__anon947d98360111::SaxEventLogger43 bool null() override 44 { 45 events.push_back("null()"); 46 return true; 47 } 48 boolean__anon947d98360111::SaxEventLogger49 bool boolean(bool val) override 50 { 51 events.push_back(val ? "boolean(true)" : "boolean(false)"); 52 return true; 53 } 54 number_integer__anon947d98360111::SaxEventLogger55 bool number_integer(json::number_integer_t val) override 56 { 57 events.push_back("number_integer(" + std::to_string(val) + ")"); 58 return true; 59 } 60 number_unsigned__anon947d98360111::SaxEventLogger61 bool number_unsigned(json::number_unsigned_t val) override 62 { 63 events.push_back("number_unsigned(" + std::to_string(val) + ")"); 64 return true; 65 } 66 number_float__anon947d98360111::SaxEventLogger67 bool number_float(json::number_float_t, const std::string& s) override 68 { 69 events.push_back("number_float(" + s + ")"); 70 return true; 71 } 72 string__anon947d98360111::SaxEventLogger73 bool string(std::string& val) override 74 { 75 events.push_back("string(" + val + ")"); 76 return true; 77 } 78 binary__anon947d98360111::SaxEventLogger79 bool binary(json::binary_t& val) override 80 { 81 std::string binary_contents = "binary("; 82 std::string comma_space = ""; 83 for (auto b : val) 84 { 85 binary_contents.append(comma_space); 86 binary_contents.append(std::to_string(static_cast<int>(b))); 87 comma_space = ", "; 88 } 89 binary_contents.append(")"); 90 events.push_back(binary_contents); 91 return true; 92 } 93 start_object__anon947d98360111::SaxEventLogger94 bool start_object(std::size_t elements) override 95 { 96 if (elements == std::size_t(-1)) 97 { 98 events.push_back("start_object()"); 99 } 100 else 101 { 102 events.push_back("start_object(" + std::to_string(elements) + ")"); 103 } 104 return true; 105 } 106 key__anon947d98360111::SaxEventLogger107 bool key(std::string& val) override 108 { 109 events.push_back("key(" + val + ")"); 110 return true; 111 } 112 end_object__anon947d98360111::SaxEventLogger113 bool end_object() override 114 { 115 events.push_back("end_object()"); 116 return true; 117 } 118 start_array__anon947d98360111::SaxEventLogger119 bool start_array(std::size_t elements) override 120 { 121 if (elements == std::size_t(-1)) 122 { 123 events.push_back("start_array()"); 124 } 125 else 126 { 127 events.push_back("start_array(" + std::to_string(elements) + ")"); 128 } 129 return true; 130 } 131 end_array__anon947d98360111::SaxEventLogger132 bool end_array() override 133 { 134 events.push_back("end_array()"); 135 return true; 136 } 137 parse_error__anon947d98360111::SaxEventLogger138 bool parse_error(std::size_t position, const std::string&, const json::exception&) override 139 { 140 events.push_back("parse_error(" + std::to_string(position) + ")"); 141 return false; 142 } 143 144 std::vector<std::string> events {}; 145 }; 146 147 struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger 148 { start_object__anon947d98360111::SaxEventLoggerExitAfterStartObject149 bool start_object(std::size_t elements) override 150 { 151 if (elements == std::size_t(-1)) 152 { 153 events.push_back("start_object()"); 154 } 155 else 156 { 157 events.push_back("start_object(" + std::to_string(elements) + ")"); 158 } 159 return false; 160 } 161 }; 162 163 struct SaxEventLoggerExitAfterKey : public SaxEventLogger 164 { key__anon947d98360111::SaxEventLoggerExitAfterKey165 bool key(std::string& val) override 166 { 167 events.push_back("key(" + val + ")"); 168 return false; 169 } 170 }; 171 172 struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger 173 { start_array__anon947d98360111::SaxEventLoggerExitAfterStartArray174 bool start_array(std::size_t elements) override 175 { 176 if (elements == std::size_t(-1)) 177 { 178 events.push_back("start_array()"); 179 } 180 else 181 { 182 events.push_back("start_array(" + std::to_string(elements) + ")"); 183 } 184 return false; 185 } 186 }; 187 } 188 189 TEST_CASE("deserialization") 190 { 191 SECTION("successful deserialization") 192 { 193 SECTION("stream") 194 { 195 std::stringstream ss1, ss2, ss3; 196 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 197 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 198 ss3 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 199 json j = json::parse(ss1); 200 CHECK(json::accept(ss2)); 201 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 202 203 SaxEventLogger l; 204 CHECK(json::sax_parse(ss3, &l)); 205 CHECK(l.events.size() == 11); 206 CHECK(l.events == std::vector<std::string>( 207 { 208 "start_array()", "string(foo)", "number_unsigned(1)", 209 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 210 "start_object()", "key(one)", "number_unsigned(1)", 211 "end_object()", "end_array()" 212 })); 213 } 214 215 SECTION("string literal") 216 { 217 auto s = "[\"foo\",1,2,3,false,{\"one\":1}]"; 218 json j = json::parse(s); 219 CHECK(json::accept(s)); 220 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 221 222 SaxEventLogger l; 223 CHECK(json::sax_parse(s, &l)); 224 CHECK(l.events.size() == 11); 225 CHECK(l.events == std::vector<std::string>( 226 { 227 "start_array()", "string(foo)", "number_unsigned(1)", 228 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 229 "start_object()", "key(one)", "number_unsigned(1)", 230 "end_object()", "end_array()" 231 })); 232 } 233 234 SECTION("string_t") 235 { 236 json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}]"; 237 json j = json::parse(s); 238 CHECK(json::accept(s)); 239 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 240 241 SaxEventLogger l; 242 CHECK(json::sax_parse(s, &l)); 243 CHECK(l.events.size() == 11); 244 CHECK(l.events == std::vector<std::string>( 245 { 246 "start_array()", "string(foo)", "number_unsigned(1)", 247 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 248 "start_object()", "key(one)", "number_unsigned(1)", 249 "end_object()", "end_array()" 250 })); 251 } 252 253 SECTION("operator<<") 254 { 255 std::stringstream ss; 256 ss << "[\"foo\",1,2,3,false,{\"one\":1}]"; 257 json j; 258 j << ss; 259 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 260 } 261 262 SECTION("operator>>") 263 { 264 std::stringstream ss; 265 ss << "[\"foo\",1,2,3,false,{\"one\":1}]"; 266 json j; 267 ss >> j; 268 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 269 } 270 271 SECTION("user-defined string literal") 272 { 273 CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 274 } 275 } 276 277 SECTION("unsuccessful deserialization") 278 { 279 SECTION("stream") 280 { 281 std::stringstream ss1, ss2, ss3, ss4, ss5; 282 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 283 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 284 ss3 << "[\"foo\",1,2,3,false,{\"one\":1}"; 285 ss4 << "[\"foo\",1,2,3,false,{\"one\":1}"; 286 ss5 << "[\"foo\",1,2,3,false,{\"one\":1}"; 287 288 json _; 289 CHECK_THROWS_AS(_ = json::parse(ss1), json::parse_error&); 290 CHECK_THROWS_WITH(_ = json::parse(ss2), 291 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 292 CHECK(!json::accept(ss3)); 293 294 json j_error; 295 CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false)); 296 CHECK(j_error.is_discarded()); 297 298 SaxEventLogger l; 299 CHECK(!json::sax_parse(ss5, &l)); 300 CHECK(l.events.size() == 11); 301 CHECK(l.events == std::vector<std::string>( 302 { 303 "start_array()", "string(foo)", "number_unsigned(1)", 304 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 305 "start_object()", "key(one)", "number_unsigned(1)", 306 "end_object()", "parse_error(29)" 307 })); 308 } 309 310 SECTION("string") 311 { 312 json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; 313 json _; 314 CHECK_THROWS_AS(_ = json::parse(s), json::parse_error&); 315 CHECK_THROWS_WITH(_ = json::parse(s), 316 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 317 CHECK(!json::accept(s)); 318 319 json j_error; 320 CHECK_NOTHROW(j_error = json::parse(s, nullptr, false)); 321 CHECK(j_error.is_discarded()); 322 323 SaxEventLogger l; 324 CHECK(!json::sax_parse(s, &l)); 325 CHECK(l.events.size() == 11); 326 CHECK(l.events == std::vector<std::string>( 327 { 328 "start_array()", "string(foo)", "number_unsigned(1)", 329 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 330 "start_object()", "key(one)", "number_unsigned(1)", 331 "end_object()", "parse_error(29)" 332 })); 333 } 334 335 SECTION("operator<<") 336 { 337 std::stringstream ss1, ss2; 338 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 339 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 340 json j; 341 CHECK_THROWS_AS(j << ss1, json::parse_error&); 342 CHECK_THROWS_WITH(j << ss2, 343 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 344 } 345 346 SECTION("operator>>") 347 { 348 std::stringstream ss1, ss2; 349 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 350 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 351 json j; 352 CHECK_THROWS_AS(ss1 >> j, json::parse_error&); 353 CHECK_THROWS_WITH(ss2 >> j, 354 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 355 } 356 357 SECTION("user-defined string literal") 358 { 359 CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&); 360 CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json, 361 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 362 } 363 } 364 365 SECTION("contiguous containers") 366 { 367 SECTION("directly") 368 { 369 SECTION("from std::vector") 370 { 371 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'}; 372 CHECK(json::parse(v) == json(true)); 373 CHECK(json::accept(v)); 374 375 SaxEventLogger l; 376 CHECK(json::sax_parse(v, &l)); 377 CHECK(l.events.size() == 1); 378 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 379 } 380 381 SECTION("from std::array") 382 { 383 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} }; 384 CHECK(json::parse(v) == json(true)); 385 CHECK(json::accept(v)); 386 387 SaxEventLogger l; 388 CHECK(json::sax_parse(v, &l)); 389 CHECK(l.events.size() == 1); 390 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 391 } 392 393 SECTION("from array") 394 { 395 uint8_t v[] = {'t', 'r', 'u', 'e'}; 396 CHECK(json::parse(v) == json(true)); 397 CHECK(json::accept(v)); 398 399 SaxEventLogger l; 400 CHECK(json::sax_parse(v, &l)); 401 CHECK(l.events.size() == 1); 402 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 403 } 404 405 SECTION("from chars") 406 { 407 uint8_t* v = new uint8_t[5]; 408 v[0] = 't'; 409 v[1] = 'r'; 410 v[2] = 'u'; 411 v[3] = 'e'; 412 v[4] = '\0'; 413 CHECK(json::parse(v) == json(true)); 414 CHECK(json::accept(v)); 415 416 SaxEventLogger l; 417 CHECK(json::sax_parse(v, &l)); 418 CHECK(l.events.size() == 1); 419 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 420 421 delete[] v; 422 } 423 424 SECTION("from std::string") 425 { 426 std::string v = {'t', 'r', 'u', 'e'}; 427 CHECK(json::parse(v) == json(true)); 428 CHECK(json::accept(v)); 429 430 SaxEventLogger l; 431 CHECK(json::sax_parse(v, &l)); 432 CHECK(l.events.size() == 1); 433 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 434 } 435 436 SECTION("from std::initializer_list") 437 { 438 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'}; 439 CHECK(json::parse(v) == json(true)); 440 CHECK(json::accept(v)); 441 442 SaxEventLogger l; 443 CHECK(json::sax_parse(v, &l)); 444 CHECK(l.events.size() == 1); 445 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 446 } 447 448 SECTION("empty container") 449 { 450 std::vector<uint8_t> v; 451 json _; 452 CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&); 453 CHECK(!json::accept(v)); 454 455 SaxEventLogger l; 456 CHECK(!json::sax_parse(v, &l)); 457 CHECK(l.events.size() == 1); 458 CHECK(l.events == std::vector<std::string>({"parse_error(1)"})); 459 } 460 } 461 462 SECTION("via iterator range") 463 { 464 SECTION("from std::vector") 465 { 466 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'}; 467 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 468 CHECK(json::accept(std::begin(v), std::end(v))); 469 470 SaxEventLogger l; 471 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 472 CHECK(l.events.size() == 1); 473 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 474 475 } 476 477 SECTION("from std::array") 478 { 479 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} }; 480 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 481 CHECK(json::accept(std::begin(v), std::end(v))); 482 483 SaxEventLogger l; 484 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 485 CHECK(l.events.size() == 1); 486 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 487 } 488 489 SECTION("from array") 490 { 491 uint8_t v[] = {'t', 'r', 'u', 'e'}; 492 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 493 CHECK(json::accept(std::begin(v), std::end(v))); 494 495 SaxEventLogger l; 496 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 497 CHECK(l.events.size() == 1); 498 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 499 } 500 501 SECTION("from std::string") 502 { 503 std::string v = {'t', 'r', 'u', 'e'}; 504 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 505 CHECK(json::accept(std::begin(v), std::end(v))); 506 507 SaxEventLogger l; 508 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 509 CHECK(l.events.size() == 1); 510 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 511 } 512 513 SECTION("from std::initializer_list") 514 { 515 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'}; 516 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 517 CHECK(json::accept(std::begin(v), std::end(v))); 518 519 SaxEventLogger l; 520 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 521 CHECK(l.events.size() == 1); 522 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 523 } 524 525 SECTION("from std::valarray") 526 { 527 std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'}; 528 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 529 CHECK(json::accept(std::begin(v), std::end(v))); 530 531 SaxEventLogger l; 532 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 533 CHECK(l.events.size() == 1); 534 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 535 } 536 537 SECTION("with empty range") 538 { 539 std::vector<uint8_t> v; 540 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 541 CHECK(!json::accept(std::begin(v), std::end(v))); 542 543 SaxEventLogger l; 544 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 545 CHECK(l.events.size() == 1); 546 CHECK(l.events == std::vector<std::string>({"parse_error(1)"})); 547 } 548 } 549 550 // these cases are required for 100% line coverage 551 SECTION("error cases") 552 { 553 SECTION("case 1") 554 { 555 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}; 556 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 557 CHECK(!json::accept(std::begin(v), std::end(v))); 558 559 json j_error; 560 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 561 CHECK(j_error.is_discarded()); 562 563 SaxEventLogger l; 564 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 565 CHECK(l.events.size() == 1); 566 CHECK(l.events == std::vector<std::string>({"parse_error(10)"})); 567 } 568 569 SECTION("case 2") 570 { 571 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}; 572 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 573 CHECK(!json::accept(std::begin(v), std::end(v))); 574 575 json j_error; 576 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 577 CHECK(j_error.is_discarded()); 578 579 SaxEventLogger l; 580 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 581 CHECK(l.events.size() == 1); 582 CHECK(l.events == std::vector<std::string>({"parse_error(11)"})); 583 } 584 585 SECTION("case 3") 586 { 587 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}; 588 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 589 CHECK(!json::accept(std::begin(v), std::end(v))); 590 591 json j_error; 592 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 593 CHECK(j_error.is_discarded()); 594 595 SaxEventLogger l; 596 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 597 CHECK(l.events.size() == 1); 598 CHECK(l.events == std::vector<std::string>({"parse_error(18)"})); 599 } 600 601 SECTION("case 4") 602 { 603 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}; 604 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 605 CHECK(!json::accept(std::begin(v), std::end(v))); 606 607 json j_error; 608 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 609 CHECK(j_error.is_discarded()); 610 611 SaxEventLogger l; 612 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 613 CHECK(l.events.size() == 1); 614 CHECK(l.events == std::vector<std::string>({"parse_error(18)"})); 615 } 616 617 SECTION("case 5") 618 { 619 uint8_t v[] = {'\"', 0x7F, 0xC1}; 620 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 621 CHECK(!json::accept(std::begin(v), std::end(v))); 622 623 json j_error; 624 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 625 CHECK(j_error.is_discarded()); 626 627 SaxEventLogger l; 628 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 629 CHECK(l.events.size() == 1); 630 CHECK(l.events == std::vector<std::string>({"parse_error(3)"})); 631 } 632 633 SECTION("case 6") 634 { 635 uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F}; 636 json _; 637 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&); 638 CHECK_THROWS_WITH(_ = json::parse(std::begin(v), std::end(v)), 639 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'"); 640 CHECK(!json::accept(std::begin(v), std::end(v))); 641 642 json j_error; 643 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 644 CHECK(j_error.is_discarded()); 645 646 SaxEventLogger l; 647 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 648 CHECK(l.events.size() == 1); 649 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 650 } 651 652 SECTION("case 7") 653 { 654 uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0}; 655 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 656 CHECK(!json::accept(std::begin(v), std::end(v))); 657 658 json j_error; 659 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 660 CHECK(j_error.is_discarded()); 661 662 SaxEventLogger l; 663 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 664 CHECK(l.events.size() == 1); 665 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 666 } 667 668 SECTION("case 8") 669 { 670 uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F}; 671 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 672 CHECK(!json::accept(std::begin(v), std::end(v))); 673 674 json j_error; 675 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 676 CHECK(j_error.is_discarded()); 677 678 SaxEventLogger l; 679 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 680 CHECK(l.events.size() == 1); 681 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 682 } 683 684 SECTION("case 9") 685 { 686 uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0}; 687 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 688 CHECK(!json::accept(std::begin(v), std::end(v))); 689 690 json j_error; 691 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 692 CHECK(j_error.is_discarded()); 693 694 SaxEventLogger l; 695 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 696 CHECK(l.events.size() == 1); 697 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 698 } 699 700 SECTION("case 10") 701 { 702 uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F}; 703 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 704 CHECK(!json::accept(std::begin(v), std::end(v))); 705 706 json j_error; 707 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 708 CHECK(j_error.is_discarded()); 709 710 SaxEventLogger l; 711 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 712 CHECK(l.events.size() == 1); 713 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 714 } 715 716 SECTION("case 11") 717 { 718 uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F}; 719 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 720 CHECK(!json::accept(std::begin(v), std::end(v))); 721 722 json j_error; 723 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 724 CHECK(j_error.is_discarded()); 725 726 SaxEventLogger l; 727 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 728 CHECK(l.events.size() == 1); 729 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 730 } 731 732 SECTION("case 12") 733 { 734 uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0}; 735 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 736 CHECK(!json::accept(std::begin(v), std::end(v))); 737 738 json j_error; 739 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 740 CHECK(j_error.is_discarded()); 741 742 SaxEventLogger l; 743 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 744 CHECK(l.events.size() == 1); 745 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 746 } 747 748 SECTION("case 13") 749 { 750 uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F}; 751 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 752 CHECK(!json::accept(std::begin(v), std::end(v))); 753 754 json j_error; 755 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 756 CHECK(j_error.is_discarded()); 757 758 SaxEventLogger l; 759 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 760 CHECK(l.events.size() == 1); 761 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 762 } 763 764 SECTION("case 14") 765 { 766 uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0}; 767 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 768 CHECK(!json::accept(std::begin(v), std::end(v))); 769 770 json j_error; 771 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 772 CHECK(j_error.is_discarded()); 773 774 SaxEventLogger l; 775 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 776 CHECK(l.events.size() == 1); 777 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 778 } 779 780 SECTION("case 15") 781 { 782 uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F}; 783 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 784 CHECK(!json::accept(std::begin(v), std::end(v))); 785 786 json j_error; 787 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 788 CHECK(j_error.is_discarded()); 789 790 SaxEventLogger l; 791 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 792 CHECK(l.events.size() == 1); 793 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 794 } 795 796 SECTION("case 16") 797 { 798 uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'}; 799 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 800 CHECK(!json::accept(std::begin(v), std::end(v))); 801 802 json j_error; 803 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 804 CHECK(j_error.is_discarded()); 805 806 SaxEventLogger l; 807 CHECK(!json::sax_parse(std::begin(v), std::end(v), &l)); 808 CHECK(l.events.size() == 4); 809 CHECK(l.events == std::vector<std::string>( 810 { 811 "start_object()", "key()", "number_unsigned(11)", 812 "parse_error(7)" 813 })); 814 } 815 } 816 } 817 818 SECTION("ignoring byte-order marks") 819 { 820 std::string bom = "\xEF\xBB\xBF"; 821 822 SECTION("BOM only") 823 { 824 json _; 825 CHECK_THROWS_AS(_ = json::parse(bom), json::parse_error&); 826 CHECK_THROWS_WITH(_ = json::parse(bom), 827 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal"); 828 829 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom)), json::parse_error&); 830 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom)), 831 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal"); 832 833 SaxEventLogger l; 834 CHECK(!json::sax_parse(bom, &l)); 835 CHECK(l.events.size() == 1); 836 CHECK(l.events == std::vector<std::string>( 837 { 838 "parse_error(4)" 839 })); 840 } 841 842 SECTION("BOM and content") 843 { 844 CHECK(json::parse(bom + "1") == 1); 845 CHECK(json::parse(std::istringstream(bom + "1")) == 1); 846 847 SaxEventLogger l1, l2; 848 CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1)); 849 CHECK(json::sax_parse(bom + "1", &l2)); 850 CHECK(l1.events.size() == 1); 851 CHECK(l1.events == std::vector<std::string>( 852 { 853 "number_unsigned(1)" 854 })); 855 CHECK(l2.events.size() == 1); 856 CHECK(l2.events == std::vector<std::string>( 857 { 858 "number_unsigned(1)" 859 })); 860 } 861 862 SECTION("2 byte of BOM") 863 { 864 json _; 865 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 2)), json::parse_error&); 866 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 2)), 867 "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'"); 868 869 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&); 870 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 2))), 871 "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF\xBB'"); 872 873 SaxEventLogger l1, l2; 874 CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1)); 875 CHECK(!json::sax_parse(bom.substr(0, 2), &l2)); 876 CHECK(l1.events.size() == 1); 877 CHECK(l1.events == std::vector<std::string>( 878 { 879 "parse_error(3)" 880 })); 881 CHECK(l2.events.size() == 1); 882 CHECK(l2.events == std::vector<std::string>( 883 { 884 "parse_error(3)" 885 })); 886 } 887 888 SECTION("1 byte of BOM") 889 { 890 json _; 891 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 1)), json::parse_error&); 892 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 1)), 893 "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'"); 894 895 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&); 896 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 1))), 897 "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid BOM; must be 0xEF 0xBB 0xBF if given; last read: '\xEF'"); 898 899 SaxEventLogger l1, l2; 900 CHECK(!json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1)); 901 CHECK(!json::sax_parse(bom.substr(0, 1), &l2)); 902 CHECK(l1.events.size() == 1); 903 CHECK(l1.events == std::vector<std::string>( 904 { 905 "parse_error(2)" 906 })); 907 CHECK(l2.events.size() == 1); 908 CHECK(l2.events == std::vector<std::string>( 909 { 910 "parse_error(2)" 911 })); 912 } 913 914 SECTION("variations") 915 { 916 // calculate variations of each byte of the BOM to make sure 917 // that the BOM and only the BOM is skipped 918 for (int i0 = -1; i0 < 2; ++i0) 919 { 920 for (int i1 = -1; i1 < 2; ++i1) 921 { 922 for (int i2 = -1; i2 < 2; ++i2) 923 { 924 // debug output for the variations 925 CAPTURE(i0) 926 CAPTURE(i1) 927 CAPTURE(i2) 928 929 std::string s = ""; 930 s.push_back(static_cast<char>(bom[0] + i0)); 931 s.push_back(static_cast<char>(bom[1] + i1)); 932 s.push_back(static_cast<char>(bom[2] + i2)); 933 934 if (i0 == 0 && i1 == 0 && i2 == 0) 935 { 936 // without any variation, we skip the BOM 937 CHECK(json::parse(s + "null") == json()); 938 CHECK(json::parse(std::istringstream(s + "null")) == json()); 939 940 SaxEventLogger l; 941 CHECK(json::sax_parse(s + "null", &l)); 942 CHECK(l.events.size() == 1); 943 CHECK(l.events == std::vector<std::string>( 944 { 945 "null()" 946 })); 947 } 948 else 949 { 950 // any variation is an error 951 json _; 952 CHECK_THROWS_AS(_ = json::parse(s + "null"), json::parse_error&); 953 CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + "null")), json::parse_error&); 954 955 SaxEventLogger l; 956 CHECK(!json::sax_parse(s + "null", &l)); 957 CHECK(l.events.size() == 1); 958 959 if (i0 != 0) 960 { 961 CHECK(l.events == std::vector<std::string>( 962 { 963 "parse_error(1)" 964 })); 965 } 966 else if (i1 != 0) 967 { 968 CHECK(l.events == std::vector<std::string>( 969 { 970 "parse_error(2)" 971 })); 972 } 973 else 974 { 975 CHECK(l.events == std::vector<std::string>( 976 { 977 "parse_error(3)" 978 })); 979 } 980 } 981 } 982 } 983 } 984 } 985 986 SECTION("preserve state after parsing") 987 { 988 std::istringstream s(bom + "123 456"); 989 json j; 990 j << s; 991 CHECK(j == 123); 992 j << s; 993 CHECK(j == 456); 994 } 995 } 996 997 SECTION("SAX and early abort") 998 { 999 std::string s = "[1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}]"; 1000 1001 SaxEventLogger default_logger; 1002 SaxEventLoggerExitAfterStartObject exit_after_start_object; 1003 SaxEventLoggerExitAfterKey exit_after_key; 1004 SaxEventLoggerExitAfterStartArray exit_after_start_array; 1005 1006 json::sax_parse(s, &default_logger); 1007 CHECK(default_logger.events.size() == 14); 1008 CHECK(default_logger.events == std::vector<std::string>( 1009 { 1010 "start_array()", "number_unsigned(1)", "start_array()", 1011 "string(string)", "number_float(43.12)", "end_array()", "null()", 1012 "start_object()", "key(key1)", "boolean(true)", "key(key2)", 1013 "boolean(false)", "end_object()", "end_array()" 1014 })); 1015 1016 json::sax_parse(s, &exit_after_start_object); 1017 CHECK(exit_after_start_object.events.size() == 8); 1018 CHECK(exit_after_start_object.events == std::vector<std::string>( 1019 { 1020 "start_array()", "number_unsigned(1)", "start_array()", 1021 "string(string)", "number_float(43.12)", "end_array()", "null()", 1022 "start_object()" 1023 })); 1024 1025 json::sax_parse(s, &exit_after_key); 1026 CHECK(exit_after_key.events.size() == 9); 1027 CHECK(exit_after_key.events == std::vector<std::string>( 1028 { 1029 "start_array()", "number_unsigned(1)", "start_array()", 1030 "string(string)", "number_float(43.12)", "end_array()", "null()", 1031 "start_object()", "key(key1)" 1032 })); 1033 1034 json::sax_parse(s, &exit_after_start_array); 1035 CHECK(exit_after_start_array.events.size() == 1); 1036 CHECK(exit_after_start_array.events == std::vector<std::string>( 1037 { 1038 "start_array()" 1039 })); 1040 } 1041 } 1042 1043 TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T, 1044 char, unsigned char, signed char, 1045 wchar_t, 1046 char16_t, char32_t, 1047 std::uint8_t, std::int8_t, 1048 std::int16_t, std::uint16_t, 1049 std::int32_t, std::uint32_t) 1050 { 1051 std::vector<T> v = {'t', 'r', 'u', 'e'}; 1052 CHECK(json::parse(v) == json(true)); 1053 CHECK(json::accept(v)); 1054 1055 SaxEventLogger l; 1056 CHECK(json::sax_parse(v, &l)); 1057 CHECK(l.events.size() == 1); 1058 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 1059 } 1060 1061 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T, 1062 char, unsigned char, std::uint8_t) 1063 { 1064 // a star emoji 1065 std::vector<T> v = {'"', static_cast<T>(0xe2), static_cast<T>(0xad), static_cast<T>(0x90), static_cast<T>(0xef), static_cast<T>(0xb8), static_cast<T>(0x8f), '"'}; 1066 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\""); 1067 CHECK(json::accept(v)); 1068 1069 SaxEventLogger l; 1070 CHECK(json::sax_parse(v, &l)); 1071 CHECK(l.events.size() == 1); 1072 } 1073 1074 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-16)", T, 1075 char16_t, std::uint16_t) 1076 { 1077 // a star emoji 1078 std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')}; 1079 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\""); 1080 CHECK(json::accept(v)); 1081 1082 SaxEventLogger l; 1083 CHECK(json::sax_parse(v, &l)); 1084 CHECK(l.events.size() == 1); 1085 } 1086 1087 TEST_CASE_TEMPLATE("deserialization of different character types (UTF-32)", T, 1088 char32_t, std::uint32_t) 1089 { 1090 // a star emoji 1091 std::vector<T> v = {static_cast<T>('"'), static_cast<T>(0x2b50), static_cast<T>(0xfe0f), static_cast<T>('"')}; 1092 CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\""); 1093 CHECK(json::accept(v)); 1094 1095 SaxEventLogger l; 1096 CHECK(json::sax_parse(v, &l)); 1097 CHECK(l.events.size() == 1); 1098 } 1099