1 /* 2 __ _____ _____ _____ 3 __| | __| | | | JSON for Modern C++ (test suite) 4 | | |__ | | | | | | version 3.7.3 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__anon147df8ed0111::SaxEventLogger43 bool null() override 44 { 45 events.push_back("null()"); 46 return true; 47 } 48 boolean__anon147df8ed0111::SaxEventLogger49 bool boolean(bool val) override 50 { 51 events.push_back(val ? "boolean(true)" : "boolean(false)"); 52 return true; 53 } 54 number_integer__anon147df8ed0111::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__anon147df8ed0111::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__anon147df8ed0111::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__anon147df8ed0111::SaxEventLogger73 bool string(std::string& val) override 74 { 75 events.push_back("string(" + val + ")"); 76 return true; 77 } 78 start_object__anon147df8ed0111::SaxEventLogger79 bool start_object(std::size_t elements) override 80 { 81 if (elements == std::size_t(-1)) 82 { 83 events.push_back("start_object()"); 84 } 85 else 86 { 87 events.push_back("start_object(" + std::to_string(elements) + ")"); 88 } 89 return true; 90 } 91 key__anon147df8ed0111::SaxEventLogger92 bool key(std::string& val) override 93 { 94 events.push_back("key(" + val + ")"); 95 return true; 96 } 97 end_object__anon147df8ed0111::SaxEventLogger98 bool end_object() override 99 { 100 events.push_back("end_object()"); 101 return true; 102 } 103 start_array__anon147df8ed0111::SaxEventLogger104 bool start_array(std::size_t elements) override 105 { 106 if (elements == std::size_t(-1)) 107 { 108 events.push_back("start_array()"); 109 } 110 else 111 { 112 events.push_back("start_array(" + std::to_string(elements) + ")"); 113 } 114 return true; 115 } 116 end_array__anon147df8ed0111::SaxEventLogger117 bool end_array() override 118 { 119 events.push_back("end_array()"); 120 return true; 121 } 122 parse_error__anon147df8ed0111::SaxEventLogger123 bool parse_error(std::size_t position, const std::string&, const json::exception&) override 124 { 125 events.push_back("parse_error(" + std::to_string(position) + ")"); 126 return false; 127 } 128 129 std::vector<std::string> events {}; 130 }; 131 132 struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger 133 { start_object__anon147df8ed0111::SaxEventLoggerExitAfterStartObject134 bool start_object(std::size_t elements) override 135 { 136 if (elements == std::size_t(-1)) 137 { 138 events.push_back("start_object()"); 139 } 140 else 141 { 142 events.push_back("start_object(" + std::to_string(elements) + ")"); 143 } 144 return false; 145 } 146 }; 147 148 struct SaxEventLoggerExitAfterKey : public SaxEventLogger 149 { key__anon147df8ed0111::SaxEventLoggerExitAfterKey150 bool key(std::string& val) override 151 { 152 events.push_back("key(" + val + ")"); 153 return false; 154 } 155 }; 156 157 struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger 158 { start_array__anon147df8ed0111::SaxEventLoggerExitAfterStartArray159 bool start_array(std::size_t elements) override 160 { 161 if (elements == std::size_t(-1)) 162 { 163 events.push_back("start_array()"); 164 } 165 else 166 { 167 events.push_back("start_array(" + std::to_string(elements) + ")"); 168 } 169 return false; 170 } 171 }; 172 } 173 174 TEST_CASE("deserialization") 175 { 176 SECTION("successful deserialization") 177 { 178 SECTION("stream") 179 { 180 std::stringstream ss1, ss2, ss3; 181 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 182 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 183 ss3 << "[\"foo\",1,2,3,false,{\"one\":1}]"; 184 json j = json::parse(ss1); 185 CHECK(json::accept(ss2)); 186 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 187 188 SaxEventLogger l; 189 CHECK(json::sax_parse(ss3, &l)); 190 CHECK(l.events.size() == 11); 191 CHECK(l.events == std::vector<std::string>( 192 { 193 "start_array()", "string(foo)", "number_unsigned(1)", 194 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 195 "start_object()", "key(one)", "number_unsigned(1)", 196 "end_object()", "end_array()" 197 })); 198 } 199 200 SECTION("string literal") 201 { 202 auto s = "[\"foo\",1,2,3,false,{\"one\":1}]"; 203 json j = json::parse(s); 204 CHECK(json::accept(s)); 205 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 206 207 SaxEventLogger l; 208 CHECK(json::sax_parse(s, &l)); 209 CHECK(l.events.size() == 11); 210 CHECK(l.events == std::vector<std::string>( 211 { 212 "start_array()", "string(foo)", "number_unsigned(1)", 213 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 214 "start_object()", "key(one)", "number_unsigned(1)", 215 "end_object()", "end_array()" 216 })); 217 } 218 219 SECTION("string_t") 220 { 221 json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}]"; 222 json j = json::parse(s); 223 CHECK(json::accept(s)); 224 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 225 226 SaxEventLogger l; 227 CHECK(json::sax_parse(s, &l)); 228 CHECK(l.events.size() == 11); 229 CHECK(l.events == std::vector<std::string>( 230 { 231 "start_array()", "string(foo)", "number_unsigned(1)", 232 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 233 "start_object()", "key(one)", "number_unsigned(1)", 234 "end_object()", "end_array()" 235 })); 236 } 237 238 SECTION("operator<<") 239 { 240 std::stringstream ss; 241 ss << "[\"foo\",1,2,3,false,{\"one\":1}]"; 242 json j; 243 j << ss; 244 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 245 } 246 247 SECTION("operator>>") 248 { 249 std::stringstream ss; 250 ss << "[\"foo\",1,2,3,false,{\"one\":1}]"; 251 json j; 252 ss >> j; 253 CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 254 } 255 256 SECTION("user-defined string literal") 257 { 258 CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}})); 259 } 260 } 261 262 SECTION("unsuccessful deserialization") 263 { 264 SECTION("stream") 265 { 266 std::stringstream ss1, ss2, ss3, ss4, ss5; 267 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 268 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 269 ss3 << "[\"foo\",1,2,3,false,{\"one\":1}"; 270 ss4 << "[\"foo\",1,2,3,false,{\"one\":1}"; 271 ss5 << "[\"foo\",1,2,3,false,{\"one\":1}"; 272 273 json _; 274 CHECK_THROWS_AS(_ = json::parse(ss1), json::parse_error&); 275 CHECK_THROWS_WITH(_ = json::parse(ss2), 276 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 277 CHECK(not json::accept(ss3)); 278 279 json j_error; 280 CHECK_NOTHROW(j_error = json::parse(ss4, nullptr, false)); 281 CHECK(j_error.is_discarded()); 282 283 SaxEventLogger l; 284 CHECK(not json::sax_parse(ss5, &l)); 285 CHECK(l.events.size() == 11); 286 CHECK(l.events == std::vector<std::string>( 287 { 288 "start_array()", "string(foo)", "number_unsigned(1)", 289 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 290 "start_object()", "key(one)", "number_unsigned(1)", 291 "end_object()", "parse_error(29)" 292 })); 293 } 294 295 SECTION("string") 296 { 297 json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; 298 json _; 299 CHECK_THROWS_AS(_ = json::parse(s), json::parse_error&); 300 CHECK_THROWS_WITH(_ = json::parse(s), 301 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 302 CHECK(not json::accept(s)); 303 304 json j_error; 305 CHECK_NOTHROW(j_error = json::parse(s, nullptr, false)); 306 CHECK(j_error.is_discarded()); 307 308 SaxEventLogger l; 309 CHECK(not json::sax_parse(s, &l)); 310 CHECK(l.events.size() == 11); 311 CHECK(l.events == std::vector<std::string>( 312 { 313 "start_array()", "string(foo)", "number_unsigned(1)", 314 "number_unsigned(2)", "number_unsigned(3)", "boolean(false)", 315 "start_object()", "key(one)", "number_unsigned(1)", 316 "end_object()", "parse_error(29)" 317 })); 318 } 319 320 SECTION("operator<<") 321 { 322 std::stringstream ss1, ss2; 323 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 324 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 325 json j; 326 CHECK_THROWS_AS(j << ss1, json::parse_error&); 327 CHECK_THROWS_WITH(j << ss2, 328 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 329 } 330 331 SECTION("operator>>") 332 { 333 std::stringstream ss1, ss2; 334 ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; 335 ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; 336 json j; 337 CHECK_THROWS_AS(ss1 >> j, json::parse_error&); 338 CHECK_THROWS_WITH(ss2 >> j, 339 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 340 } 341 342 SECTION("user-defined string literal") 343 { 344 CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error&); 345 CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json, 346 "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'"); 347 } 348 } 349 350 SECTION("contiguous containers") 351 { 352 SECTION("directly") 353 { 354 SECTION("from std::vector") 355 { 356 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'}; 357 CHECK(json::parse(v) == json(true)); 358 CHECK(json::accept(v)); 359 360 SaxEventLogger l; 361 CHECK(json::sax_parse(v, &l)); 362 CHECK(l.events.size() == 1); 363 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 364 } 365 366 SECTION("from std::array") 367 { 368 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} }; 369 CHECK(json::parse(v) == json(true)); 370 CHECK(json::accept(v)); 371 372 SaxEventLogger l; 373 CHECK(json::sax_parse(v, &l)); 374 CHECK(l.events.size() == 1); 375 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 376 } 377 378 SECTION("from array") 379 { 380 uint8_t v[] = {'t', 'r', 'u', 'e'}; 381 CHECK(json::parse(v) == json(true)); 382 CHECK(json::accept(v)); 383 384 SaxEventLogger l; 385 CHECK(json::sax_parse(v, &l)); 386 CHECK(l.events.size() == 1); 387 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 388 } 389 390 SECTION("from chars") 391 { 392 uint8_t* v = new uint8_t[5]; 393 v[0] = 't'; 394 v[1] = 'r'; 395 v[2] = 'u'; 396 v[3] = 'e'; 397 v[4] = '\0'; 398 CHECK(json::parse(v) == json(true)); 399 CHECK(json::accept(v)); 400 401 SaxEventLogger l; 402 CHECK(json::sax_parse(v, &l)); 403 CHECK(l.events.size() == 1); 404 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 405 406 delete[] v; 407 } 408 409 SECTION("from std::string") 410 { 411 std::string v = {'t', 'r', 'u', 'e'}; 412 CHECK(json::parse(v) == json(true)); 413 CHECK(json::accept(v)); 414 415 SaxEventLogger l; 416 CHECK(json::sax_parse(v, &l)); 417 CHECK(l.events.size() == 1); 418 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 419 } 420 421 SECTION("from std::initializer_list") 422 { 423 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'}; 424 CHECK(json::parse(v) == json(true)); 425 CHECK(json::accept(v)); 426 427 SaxEventLogger l; 428 CHECK(json::sax_parse(v, &l)); 429 CHECK(l.events.size() == 1); 430 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 431 } 432 433 SECTION("empty container") 434 { 435 std::vector<uint8_t> v; 436 json _; 437 CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&); 438 CHECK(not json::accept(v)); 439 440 SaxEventLogger l; 441 CHECK(not json::sax_parse(v, &l)); 442 CHECK(l.events.size() == 1); 443 CHECK(l.events == std::vector<std::string>({"parse_error(1)"})); 444 } 445 } 446 447 SECTION("via iterator range") 448 { 449 SECTION("from std::vector") 450 { 451 std::vector<uint8_t> v = {'t', 'r', 'u', 'e'}; 452 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 453 CHECK(json::accept(std::begin(v), std::end(v))); 454 455 SaxEventLogger l; 456 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 457 CHECK(l.events.size() == 1); 458 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 459 460 } 461 462 SECTION("from std::array") 463 { 464 std::array<uint8_t, 5> v { {'t', 'r', 'u', 'e'} }; 465 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 466 CHECK(json::accept(std::begin(v), std::end(v))); 467 468 SaxEventLogger l; 469 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 470 CHECK(l.events.size() == 1); 471 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 472 } 473 474 SECTION("from array") 475 { 476 uint8_t v[] = {'t', 'r', 'u', 'e'}; 477 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 478 CHECK(json::accept(std::begin(v), std::end(v))); 479 480 SaxEventLogger l; 481 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 482 CHECK(l.events.size() == 1); 483 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 484 } 485 486 SECTION("from std::string") 487 { 488 std::string v = {'t', 'r', 'u', 'e'}; 489 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 490 CHECK(json::accept(std::begin(v), std::end(v))); 491 492 SaxEventLogger l; 493 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 494 CHECK(l.events.size() == 1); 495 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 496 } 497 498 SECTION("from std::initializer_list") 499 { 500 std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e'}; 501 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 502 CHECK(json::accept(std::begin(v), std::end(v))); 503 504 SaxEventLogger l; 505 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 506 CHECK(l.events.size() == 1); 507 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 508 } 509 510 SECTION("from std::valarray") 511 { 512 std::valarray<uint8_t> v = {'t', 'r', 'u', 'e'}; 513 CHECK(json::parse(std::begin(v), std::end(v)) == json(true)); 514 CHECK(json::accept(std::begin(v), std::end(v))); 515 516 SaxEventLogger l; 517 CHECK(json::sax_parse(std::begin(v), std::end(v), &l)); 518 CHECK(l.events.size() == 1); 519 CHECK(l.events == std::vector<std::string>({"boolean(true)"})); 520 } 521 522 SECTION("with empty range") 523 { 524 std::vector<uint8_t> v; 525 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 526 CHECK(not json::accept(std::begin(v), std::end(v))); 527 528 SaxEventLogger l; 529 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 530 CHECK(l.events.size() == 1); 531 CHECK(l.events == std::vector<std::string>({"parse_error(1)"})); 532 } 533 } 534 535 // these cases are required for 100% line coverage 536 SECTION("error cases") 537 { 538 SECTION("case 1") 539 { 540 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}; 541 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 542 CHECK(not json::accept(std::begin(v), std::end(v))); 543 544 json j_error; 545 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 546 CHECK(j_error.is_discarded()); 547 548 SaxEventLogger l; 549 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 550 CHECK(l.events.size() == 1); 551 CHECK(l.events == std::vector<std::string>({"parse_error(10)"})); 552 } 553 554 SECTION("case 2") 555 { 556 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}; 557 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 558 CHECK(not json::accept(std::begin(v), std::end(v))); 559 560 json j_error; 561 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 562 CHECK(j_error.is_discarded()); 563 564 SaxEventLogger l; 565 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 566 CHECK(l.events.size() == 1); 567 CHECK(l.events == std::vector<std::string>({"parse_error(11)"})); 568 } 569 570 SECTION("case 3") 571 { 572 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}; 573 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 574 CHECK(not json::accept(std::begin(v), std::end(v))); 575 576 json j_error; 577 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 578 CHECK(j_error.is_discarded()); 579 580 SaxEventLogger l; 581 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 582 CHECK(l.events.size() == 1); 583 CHECK(l.events == std::vector<std::string>({"parse_error(18)"})); 584 } 585 586 SECTION("case 4") 587 { 588 uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}; 589 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 590 CHECK(not json::accept(std::begin(v), std::end(v))); 591 592 json j_error; 593 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 594 CHECK(j_error.is_discarded()); 595 596 SaxEventLogger l; 597 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 598 CHECK(l.events.size() == 1); 599 CHECK(l.events == std::vector<std::string>({"parse_error(18)"})); 600 } 601 602 SECTION("case 5") 603 { 604 uint8_t v[] = {'\"', 0x7F, 0xC1}; 605 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 606 CHECK(not json::accept(std::begin(v), std::end(v))); 607 608 json j_error; 609 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 610 CHECK(j_error.is_discarded()); 611 612 SaxEventLogger l; 613 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 614 CHECK(l.events.size() == 1); 615 CHECK(l.events == std::vector<std::string>({"parse_error(3)"})); 616 } 617 618 SECTION("case 6") 619 { 620 uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F}; 621 json _; 622 CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&); 623 CHECK_THROWS_WITH(_ = json::parse(std::begin(v), std::end(v)), 624 "[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'"); 625 CHECK(not json::accept(std::begin(v), std::end(v))); 626 627 json j_error; 628 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 629 CHECK(j_error.is_discarded()); 630 631 SaxEventLogger l; 632 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 633 CHECK(l.events.size() == 1); 634 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 635 } 636 637 SECTION("case 7") 638 { 639 uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0}; 640 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 641 CHECK(not json::accept(std::begin(v), std::end(v))); 642 643 json j_error; 644 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 645 CHECK(j_error.is_discarded()); 646 647 SaxEventLogger l; 648 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 649 CHECK(l.events.size() == 1); 650 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 651 } 652 653 SECTION("case 8") 654 { 655 uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F}; 656 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 657 CHECK(not json::accept(std::begin(v), std::end(v))); 658 659 json j_error; 660 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 661 CHECK(j_error.is_discarded()); 662 663 SaxEventLogger l; 664 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 665 CHECK(l.events.size() == 1); 666 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 667 } 668 669 SECTION("case 9") 670 { 671 uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0}; 672 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 673 CHECK(not json::accept(std::begin(v), std::end(v))); 674 675 json j_error; 676 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 677 CHECK(j_error.is_discarded()); 678 679 SaxEventLogger l; 680 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 681 CHECK(l.events.size() == 1); 682 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 683 } 684 685 SECTION("case 10") 686 { 687 uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F}; 688 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 689 CHECK(not json::accept(std::begin(v), std::end(v))); 690 691 json j_error; 692 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 693 CHECK(j_error.is_discarded()); 694 695 SaxEventLogger l; 696 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 697 CHECK(l.events.size() == 1); 698 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 699 } 700 701 SECTION("case 11") 702 { 703 uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F}; 704 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 705 CHECK(not json::accept(std::begin(v), std::end(v))); 706 707 json j_error; 708 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 709 CHECK(j_error.is_discarded()); 710 711 SaxEventLogger l; 712 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 713 CHECK(l.events.size() == 1); 714 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 715 } 716 717 SECTION("case 12") 718 { 719 uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0}; 720 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 721 CHECK(not json::accept(std::begin(v), std::end(v))); 722 723 json j_error; 724 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 725 CHECK(j_error.is_discarded()); 726 727 SaxEventLogger l; 728 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 729 CHECK(l.events.size() == 1); 730 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 731 } 732 733 SECTION("case 13") 734 { 735 uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F}; 736 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 737 CHECK(not json::accept(std::begin(v), std::end(v))); 738 739 json j_error; 740 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 741 CHECK(j_error.is_discarded()); 742 743 SaxEventLogger l; 744 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 745 CHECK(l.events.size() == 1); 746 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 747 } 748 749 SECTION("case 14") 750 { 751 uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0}; 752 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 753 CHECK(not json::accept(std::begin(v), std::end(v))); 754 755 json j_error; 756 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 757 CHECK(j_error.is_discarded()); 758 759 SaxEventLogger l; 760 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 761 CHECK(l.events.size() == 1); 762 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 763 } 764 765 SECTION("case 15") 766 { 767 uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F}; 768 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 769 CHECK(not json::accept(std::begin(v), std::end(v))); 770 771 json j_error; 772 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 773 CHECK(j_error.is_discarded()); 774 775 SaxEventLogger l; 776 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 777 CHECK(l.events.size() == 1); 778 CHECK(l.events == std::vector<std::string>({"parse_error(4)"})); 779 } 780 781 SECTION("case 16") 782 { 783 uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'}; 784 CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&); 785 CHECK(not json::accept(std::begin(v), std::end(v))); 786 787 json j_error; 788 CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false)); 789 CHECK(j_error.is_discarded()); 790 791 SaxEventLogger l; 792 CHECK(not json::sax_parse(std::begin(v), std::end(v), &l)); 793 CHECK(l.events.size() == 4); 794 CHECK(l.events == std::vector<std::string>( 795 { 796 "start_object()", "key()", "number_unsigned(11)", 797 "parse_error(7)" 798 })); 799 } 800 } 801 } 802 803 SECTION("ignoring byte-order marks") 804 { 805 std::string bom = "\xEF\xBB\xBF"; 806 807 SECTION("BOM only") 808 { 809 json _; 810 CHECK_THROWS_AS(_ = json::parse(bom), json::parse_error&); 811 CHECK_THROWS_WITH(_ = json::parse(bom), 812 "[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"); 813 814 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom)), json::parse_error&); 815 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom)), 816 "[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"); 817 818 SaxEventLogger l; 819 CHECK(not json::sax_parse(bom, &l)); 820 CHECK(l.events.size() == 1); 821 CHECK(l.events == std::vector<std::string>( 822 { 823 "parse_error(4)" 824 })); 825 } 826 827 SECTION("BOM and content") 828 { 829 CHECK(json::parse(bom + "1") == 1); 830 CHECK(json::parse(std::istringstream(bom + "1")) == 1); 831 832 SaxEventLogger l1, l2; 833 CHECK(json::sax_parse(std::istringstream(bom + "1"), &l1)); 834 CHECK(json::sax_parse(bom + "1", &l2)); 835 CHECK(l1.events.size() == 1); 836 CHECK(l1.events == std::vector<std::string>( 837 { 838 "number_unsigned(1)" 839 })); 840 CHECK(l2.events.size() == 1); 841 CHECK(l2.events == std::vector<std::string>( 842 { 843 "number_unsigned(1)" 844 })); 845 } 846 847 SECTION("2 byte of BOM") 848 { 849 json _; 850 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 2)), json::parse_error&); 851 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 2)), 852 "[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'"); 853 854 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 2))), json::parse_error&); 855 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 2))), 856 "[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'"); 857 858 SaxEventLogger l1, l2; 859 CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 2)), &l1)); 860 CHECK(not json::sax_parse(bom.substr(0, 2), &l2)); 861 CHECK(l1.events.size() == 1); 862 CHECK(l1.events == std::vector<std::string>( 863 { 864 "parse_error(3)" 865 })); 866 CHECK(l2.events.size() == 1); 867 CHECK(l2.events == std::vector<std::string>( 868 { 869 "parse_error(3)" 870 })); 871 } 872 873 SECTION("1 byte of BOM") 874 { 875 json _; 876 CHECK_THROWS_AS(_ = json::parse(bom.substr(0, 1)), json::parse_error&); 877 CHECK_THROWS_WITH(_ = json::parse(bom.substr(0, 1)), 878 "[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'"); 879 880 CHECK_THROWS_AS(_ = json::parse(std::istringstream(bom.substr(0, 1))), json::parse_error&); 881 CHECK_THROWS_WITH(_ = json::parse(std::istringstream(bom.substr(0, 1))), 882 "[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'"); 883 884 SaxEventLogger l1, l2; 885 CHECK(not json::sax_parse(std::istringstream(bom.substr(0, 1)), &l1)); 886 CHECK(not json::sax_parse(bom.substr(0, 1), &l2)); 887 CHECK(l1.events.size() == 1); 888 CHECK(l1.events == std::vector<std::string>( 889 { 890 "parse_error(2)" 891 })); 892 CHECK(l2.events.size() == 1); 893 CHECK(l2.events == std::vector<std::string>( 894 { 895 "parse_error(2)" 896 })); 897 } 898 899 SECTION("variations") 900 { 901 // calculate variations of each byte of the BOM to make sure 902 // that the BOM and only the BOM is skipped 903 for (int i0 = -1; i0 < 2; ++i0) 904 { 905 for (int i1 = -1; i1 < 2; ++i1) 906 { 907 for (int i2 = -1; i2 < 2; ++i2) 908 { 909 // debug output for the variations 910 CAPTURE(i0) 911 CAPTURE(i1) 912 CAPTURE(i2) 913 914 std::string s = ""; 915 s.push_back(static_cast<char>(bom[0] + i0)); 916 s.push_back(static_cast<char>(bom[1] + i1)); 917 s.push_back(static_cast<char>(bom[2] + i2)); 918 919 if (i0 == 0 and i1 == 0 and i2 == 0) 920 { 921 // without any variation, we skip the BOM 922 CHECK(json::parse(s + "null") == json()); 923 CHECK(json::parse(std::istringstream(s + "null")) == json()); 924 925 SaxEventLogger l; 926 CHECK(json::sax_parse(s + "null", &l)); 927 CHECK(l.events.size() == 1); 928 CHECK(l.events == std::vector<std::string>( 929 { 930 "null()" 931 })); 932 } 933 else 934 { 935 // any variation is an error 936 json _; 937 CHECK_THROWS_AS(_ = json::parse(s + "null"), json::parse_error&); 938 CHECK_THROWS_AS(_ = json::parse(std::istringstream(s + "null")), json::parse_error&); 939 940 SaxEventLogger l; 941 CHECK(not json::sax_parse(s + "null", &l)); 942 CHECK(l.events.size() == 1); 943 944 if (i0 != 0) 945 { 946 CHECK(l.events == std::vector<std::string>( 947 { 948 "parse_error(1)" 949 })); 950 } 951 else if (i1 != 0) 952 { 953 CHECK(l.events == std::vector<std::string>( 954 { 955 "parse_error(2)" 956 })); 957 } 958 else 959 { 960 CHECK(l.events == std::vector<std::string>( 961 { 962 "parse_error(3)" 963 })); 964 } 965 } 966 } 967 } 968 } 969 } 970 971 SECTION("preserve state after parsing") 972 { 973 std::istringstream s(bom + "123 456"); 974 json j; 975 j << s; 976 CHECK(j == 123); 977 j << s; 978 CHECK(j == 456); 979 } 980 } 981 982 SECTION("SAX and early abort") 983 { 984 std::string s = "[1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}]"; 985 986 SaxEventLogger default_logger; 987 SaxEventLoggerExitAfterStartObject exit_after_start_object; 988 SaxEventLoggerExitAfterKey exit_after_key; 989 SaxEventLoggerExitAfterStartArray exit_after_start_array; 990 991 json::sax_parse(s, &default_logger); 992 CHECK(default_logger.events.size() == 14); 993 CHECK(default_logger.events == std::vector<std::string>( 994 { 995 "start_array()", "number_unsigned(1)", "start_array()", 996 "string(string)", "number_float(43.12)", "end_array()", "null()", 997 "start_object()", "key(key1)", "boolean(true)", "key(key2)", 998 "boolean(false)", "end_object()", "end_array()" 999 })); 1000 1001 json::sax_parse(s, &exit_after_start_object); 1002 CHECK(exit_after_start_object.events.size() == 8); 1003 CHECK(exit_after_start_object.events == std::vector<std::string>( 1004 { 1005 "start_array()", "number_unsigned(1)", "start_array()", 1006 "string(string)", "number_float(43.12)", "end_array()", "null()", 1007 "start_object()" 1008 })); 1009 1010 json::sax_parse(s, &exit_after_key); 1011 CHECK(exit_after_key.events.size() == 9); 1012 CHECK(exit_after_key.events == std::vector<std::string>( 1013 { 1014 "start_array()", "number_unsigned(1)", "start_array()", 1015 "string(string)", "number_float(43.12)", "end_array()", "null()", 1016 "start_object()", "key(key1)" 1017 })); 1018 1019 json::sax_parse(s, &exit_after_start_array); 1020 CHECK(exit_after_start_array.events.size() == 1); 1021 CHECK(exit_after_start_array.events == std::vector<std::string>( 1022 { 1023 "start_array()" 1024 })); 1025 } 1026 } 1027