PageRenderTime 134ms CodeModel.GetById 40ms RepoModel.GetById 20ms app.codeStats 1ms

/libs/json/test/basic_parser.cpp

https://bitbucket.org/bosp/external-boost
C++ | 1491 lines | 1329 code | 130 blank | 32 comment | 70 complexity | 25996887681ce42d0ed3cc9d81f09965 MD5 | raw file
Possible License(s): MIT
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/json
  9. //
  10. // Test that header file is self-contained.
  11. #include <boost/json/basic_parser_impl.hpp>
  12. #include <memory>
  13. #include <string>
  14. #include <utility>
  15. #include "parse-vectors.hpp"
  16. #include "test.hpp"
  17. #include "test_suite.hpp"
  18. BOOST_JSON_NS_BEGIN
  19. BOOST_STATIC_ASSERT( std::is_nothrow_destructible<basic_parser<int>>::value );
  20. namespace base64 {
  21. std::size_t constexpr
  22. decoded_size(std::size_t n)
  23. {
  24. return n / 4 * 3; // requires n&3==0, smaller
  25. }
  26. signed char const*
  27. get_inverse()
  28. {
  29. static signed char constexpr tab[] = {
  30. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
  31. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
  32. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
  33. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
  34. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
  35. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
  36. -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
  37. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
  38. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
  39. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
  40. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
  41. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
  42. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
  43. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
  44. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
  45. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
  46. };
  47. return &tab[0];
  48. }
  49. std::pair<std::size_t, std::size_t>
  50. decode(void* dest, char const* src, std::size_t len)
  51. {
  52. char* out = static_cast<char*>(dest);
  53. auto in = reinterpret_cast<unsigned char const*>(src);
  54. unsigned char c3[3], c4[4];
  55. int i = 0;
  56. int j = 0;
  57. auto const inverse = base64::get_inverse();
  58. while(len-- && *in != '=')
  59. {
  60. auto const v = inverse[*in];
  61. if(v == -1)
  62. break;
  63. ++in;
  64. c4[i] = v;
  65. if(++i == 4)
  66. {
  67. c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
  68. c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
  69. c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
  70. for(i = 0; i < 3; i++)
  71. *out++ = c3[i];
  72. i = 0;
  73. }
  74. }
  75. if(i)
  76. {
  77. c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
  78. c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
  79. c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
  80. for(j = 0; j < i - 1; j++)
  81. *out++ = c3[j];
  82. }
  83. return {out - static_cast<char*>(dest),
  84. in - reinterpret_cast<unsigned char const*>(src)};
  85. }
  86. } // base64
  87. namespace {
  88. bool
  89. validate( string_view s )
  90. {
  91. // Parse with the null parser and return false on error
  92. null_parser p;
  93. error_code ec;
  94. p.write( s.data(), s.size(), ec );
  95. if( ec )
  96. return false;
  97. // The string is valid JSON.
  98. return true;
  99. }
  100. parse_options
  101. make_options(
  102. bool comments,
  103. bool commas,
  104. bool utf8)
  105. {
  106. parse_options opt;
  107. opt.allow_comments = comments;
  108. opt.allow_trailing_commas = commas;
  109. opt.allow_invalid_utf8 = utf8;
  110. return opt;
  111. }
  112. } // (anon)
  113. class basic_parser_test
  114. {
  115. public:
  116. ::test_suite::log_type log;
  117. void
  118. grind_one(
  119. string_view s,
  120. bool good,
  121. parse_options po)
  122. {
  123. error_code ec;
  124. fail_parser p(po);
  125. p.write(false,
  126. s.data(), s.size(), ec);
  127. BOOST_TEST((good && !ec) ||
  128. (! good && ec));
  129. }
  130. void
  131. grind_one(
  132. string_view s,
  133. bool good,
  134. const std::vector<parse_options>& configs)
  135. {
  136. for (const parse_options& po : configs)
  137. grind_one(s, good, po);
  138. }
  139. void
  140. grind(
  141. string_view s,
  142. bool good,
  143. parse_options po)
  144. {
  145. grind_one(s, good, po);
  146. // split/errors matrix
  147. if(! s.empty())
  148. {
  149. for(std::size_t i = 1;
  150. i < s.size(); ++i)
  151. {
  152. for(std::size_t j = 1;;++j)
  153. {
  154. error_code ec;
  155. fail_parser p(j, po);
  156. p.write(true, s.data(), i, ec);
  157. if(ec == error::test_failure)
  158. continue;
  159. if(! ec)
  160. {
  161. p.write(false, s.data() + i,
  162. s.size() - i, ec);
  163. if(ec == error::test_failure)
  164. continue;
  165. }
  166. BOOST_TEST((good && !ec) || (
  167. ! good && ec));
  168. break;
  169. }
  170. }
  171. }
  172. // split/exceptions matrix
  173. if(! s.empty())
  174. {
  175. for(std::size_t i = 1;
  176. i < s.size(); ++i)
  177. {
  178. for(std::size_t j = 1;;++j)
  179. {
  180. error_code ec;
  181. throw_parser p(j, po);
  182. try
  183. {
  184. p.write(
  185. true, s.data(), i, ec);
  186. if(! ec)
  187. p.write(
  188. false, s.data() + i,
  189. s.size() - i, ec);
  190. BOOST_TEST((good && !ec) || (
  191. ! good && ec));
  192. break;
  193. }
  194. catch(test_exception const&)
  195. {
  196. continue;
  197. }
  198. catch(std::exception const& e)
  199. {
  200. BOOST_TEST_FAIL();
  201. log << " " <<
  202. e.what() << std::endl;
  203. }
  204. }
  205. }
  206. }
  207. }
  208. void
  209. grind(
  210. string_view s,
  211. bool good,
  212. const std::vector<parse_options>& configs)
  213. {
  214. for (const parse_options& po : configs)
  215. grind(s, good, po);
  216. }
  217. void
  218. bad(string_view s)
  219. {
  220. grind(s, false, parse_options());
  221. }
  222. void
  223. good(string_view s)
  224. {
  225. grind(s, true, parse_options());
  226. }
  227. void
  228. bad(
  229. string_view s,
  230. const parse_options& po)
  231. {
  232. grind(s, false, po);
  233. }
  234. void
  235. good(
  236. string_view s,
  237. const parse_options& po)
  238. {
  239. grind(s, true, po);
  240. }
  241. void
  242. bad_one(
  243. string_view s,
  244. const parse_options& po)
  245. {
  246. grind_one(s, false, po);
  247. }
  248. void
  249. good_one(
  250. string_view s,
  251. const parse_options& po)
  252. {
  253. grind_one(s, true, po);
  254. }
  255. void
  256. bad_one(string_view s)
  257. {
  258. grind_one(s, false, parse_options());
  259. }
  260. void
  261. good_one(string_view s)
  262. {
  263. grind_one(s, true, parse_options());
  264. }
  265. //------------------------------------------------------
  266. void
  267. testNull()
  268. {
  269. good("null");
  270. good(" null");
  271. good("null ");
  272. good("\tnull");
  273. good("null\t");
  274. good("\r\n\t null\r\n\t ");
  275. bad ("n ");
  276. bad ("nu ");
  277. bad ("nul ");
  278. bad ("n--- ");
  279. bad ("nu-- ");
  280. bad ("nul- ");
  281. bad ("NULL");
  282. bad ("Null");
  283. bad ("nulls");
  284. }
  285. void
  286. testBoolean()
  287. {
  288. good("true");
  289. good(" true");
  290. good("true ");
  291. good("\ttrue");
  292. good("true\t");
  293. good("\r\n\t true\r\n\t ");
  294. bad ("t ");
  295. bad ("tr ");
  296. bad ("tru ");
  297. bad ("t--- ");
  298. bad ("tr-- ");
  299. bad ("tru- ");
  300. bad ("TRUE");
  301. bad ("True");
  302. bad ("truer");
  303. good("false");
  304. good(" false");
  305. good("false ");
  306. good("\tfalse");
  307. good("false\t");
  308. good("\r\n\t false\r\n\t ");
  309. bad ("f ");
  310. bad ("fa ");
  311. bad ("fal ");
  312. bad ("fals ");
  313. bad ("f---- ");
  314. bad ("fa--- ");
  315. bad ("fal-- ");
  316. bad ("fals- ");
  317. bad ("FALSE");
  318. bad ("False");
  319. bad ("falser");
  320. }
  321. void
  322. testString()
  323. {
  324. good(R"jv( "x" )jv");
  325. good(R"jv( "xy" )jv");
  326. good(R"jv( "x y" )jv");
  327. // escapes
  328. good(R"jv(" \" ")jv");
  329. good(R"jv(" \\ ")jv");
  330. good(R"jv(" \/ ")jv");
  331. good(R"jv(" \b ")jv");
  332. good(R"jv(" \f ")jv");
  333. good(R"jv(" \n ")jv");
  334. good(R"jv(" \r ")jv");
  335. good(R"jv(" \t ")jv");
  336. // utf-16 escapes
  337. good(R"jv( " \u0000 " )jv");
  338. good(R"jv( " \ud7ff " )jv");
  339. good(R"jv( " \ue000 " )jv");
  340. good(R"jv( " \uffff " )jv");
  341. good(R"jv( " \ud800\udc00 " )jv");
  342. good(R"jv( " \udbff\udfff " )jv");
  343. good(R"jv( " \n\u0000 " )jv");
  344. // escape in key
  345. good(R"jv( {" \n":null} )jv");
  346. // incomplete
  347. bad ("\"");
  348. // illegal control character
  349. bad ({ "\"" "\x00" "\"", 3 });
  350. bad ("\"" "\x1f" "\"");
  351. bad ("\"" "\\n" "\x1f" "\"");
  352. // incomplete escape
  353. bad (R"jv( "\" )jv");
  354. // invalid escape
  355. bad (R"jv( "\z" )jv");
  356. // utf-16 escape, fast path,
  357. // invalid surrogate
  358. bad (R"jv( " \u---- " )jv");
  359. bad (R"jv( " \ud--- " )jv");
  360. bad (R"jv( " \ud8-- " )jv");
  361. bad (R"jv( " \ud80- " )jv");
  362. // invalid low surrogate
  363. bad (R"jv( " \ud800------ " )jv");
  364. bad (R"jv( " \ud800\----- " )jv");
  365. bad (R"jv( " \ud800\u---- " )jv");
  366. bad (R"jv( " \ud800\ud--- " )jv");
  367. bad (R"jv( " \ud800\udc-- " )jv");
  368. bad (R"jv( " \ud800\udc0- " )jv");
  369. // illegal leading surrogate
  370. bad (R"jv( " \udc00 " )jv");
  371. bad (R"jv( " \udfff " )jv");
  372. // illegal trailing surrogate
  373. bad (R"jv( " \ud800\udbff " )jv");
  374. bad (R"jv( " \ud800\ue000 " )jv");
  375. }
  376. void
  377. testNumber()
  378. {
  379. good("0");
  380. good("0 ");
  381. good("0e0 ");
  382. good("0E0 ");
  383. good("0e00 ");
  384. good("0E01 ");
  385. good("0e+0 ");
  386. good("0e-0 ");
  387. good("0.0 ");
  388. good("0.01 ");
  389. good("0.0e0 ");
  390. good("0.01e+0 ");
  391. good("0.02E-0 ");
  392. good("1 ");
  393. good("12 ");
  394. good("1e0 ");
  395. good("1E0 ");
  396. good("1e00 ");
  397. good("1E01 ");
  398. good("1e+0 ");
  399. good("1e-0 ");
  400. good("1.0 ");
  401. good("1.01 ");
  402. good("1.0e0 ");
  403. good("1.01e+0 ");
  404. good("1.02E-0 ");
  405. good("1.0");
  406. good("-0 ");
  407. good("-0e0 ");
  408. good("-0E0 ");
  409. good("-0e00 ");
  410. good("-0E01 ");
  411. good("-0e+0 ");
  412. good("-0e-0 ");
  413. good("-0.0 ");
  414. good("-0.01 ");
  415. good("-0.0e0 ");
  416. good("-0.01e+0 ");
  417. good("-0.02E-0 ");
  418. good("-1 ");
  419. good("-12 ");
  420. good("-1 ");
  421. good("-1e0 ");
  422. good("-1E0 ");
  423. good("-1e00 ");
  424. good("-1E01 ");
  425. good("-1e+0 ");
  426. good("-1e-0 ");
  427. good("-1.0 ");
  428. good("-1.01 ");
  429. good("-1.0e0 ");
  430. good("-1.01e+0 ");
  431. good("-1.02E-0 ");
  432. good("-1.0");
  433. good("1.1e309 ");
  434. good("9223372036854775807 ");
  435. good("-9223372036854775807 ");
  436. good("18446744073709551615 ");
  437. good("-18446744073709551615 ");
  438. good("1234567890123456");
  439. good("-1234567890123456");
  440. good("10000000000000000000000000");
  441. good("0.900719925474099178 ");
  442. // non-significant digits
  443. good("1000000000000000000000000 ");
  444. good("1000000000000000000000000e1 ");
  445. good("1000000000000000000000000.0 ");
  446. good("1000000000000000000000000.00 ");
  447. good("1000000000000000000000000.000000000001");
  448. good("1000000000000000000000000.0e1 ");
  449. good("1000000000000000000000000.0 ");
  450. good("1000000000.1000000000 ");
  451. bad("");
  452. bad("- ");
  453. bad("00 ");
  454. bad("01 ");
  455. bad("00. ");
  456. bad("00.0 ");
  457. bad("-00 ");
  458. bad("-01 ");
  459. bad("-00. ");
  460. bad("-00.0 ");
  461. bad("1a ");
  462. bad("-a ");
  463. bad(". ");
  464. bad("1. ");
  465. bad("1+ ");
  466. bad("0.0+ ");
  467. bad("0.0e+ ");
  468. bad("0.0e- ");
  469. bad("0.0e0- ");
  470. bad("0.0e ");
  471. bad("1eX ");
  472. bad("1000000000000000000000000.e ");
  473. bad("0.");
  474. bad("0.0e+");
  475. bad("0.0e2147483648");
  476. }
  477. void
  478. testArray()
  479. {
  480. good("[]");
  481. good("[ ]");
  482. good("[ \t ]");
  483. good("[ \"\" ]");
  484. good("[ \" \" ]");
  485. good("[ \"x\" ]");
  486. good("[ \"x\", \"y\" ]");
  487. good("[1,2,3]");
  488. good(" [1,2,3]");
  489. good("[1,2,3] ");
  490. good(" [1,2,3] ");
  491. good("[1,2,3]");
  492. good("[ 1,2,3]");
  493. good("[1 ,2,3]");
  494. good("[1, 2,3]");
  495. good("[1,2 ,3]");
  496. good("[1,2, 3]");
  497. good("[1,2,3 ]");
  498. good(" [ 1 , 2 \t\n , \n3]");
  499. bad ("[");
  500. bad (" [");
  501. bad (" []]");
  502. bad ("[{]");
  503. bad (R"jv( [ null ; 1 ] )jv");
  504. }
  505. void
  506. testObject()
  507. {
  508. good("{}");
  509. good("{ }");
  510. good("{ \t }");
  511. good("{\"x\":null}");
  512. good("{ \"x\":null}");
  513. good("{\"x\" :null}");
  514. good("{\"x\": null}");
  515. good("{\"x\":null }");
  516. good("{ \"x\" : null }");
  517. good("{ \"x\" : {} }");
  518. good("{ \"x\" : [] }");
  519. good("{ \"x\" : { \"y\" : null } }");
  520. good("{ \"x\" : [{}] }");
  521. good("{\"x\\ny\\u0022\":null}");
  522. good("{ \"x\":1, \"y\":null}");
  523. good("{\"x\":1,\"y\":2,\"z\":3}");
  524. good(" {\"x\":1,\"y\":2,\"z\":3}");
  525. good("{\"x\":1,\"y\":2,\"z\":3} ");
  526. good(" {\"x\":1,\"y\":2,\"z\":3} ");
  527. good("{ \"x\":1,\"y\":2,\"z\":3}");
  528. good("{\"x\" :1,\"y\":2,\"z\":3}");
  529. good("{\"x\":1 ,\"y\":2,\"z\":3}");
  530. good("{\"x\":1,\"y\" :2,\"z\":3}");
  531. good("{\"x\":1,\"y\": 2,\"z\":3}");
  532. good("{\"x\":1,\"y\":2 ,\"z\":3}");
  533. good("{\"x\":1,\"y\":2, \"z\":3}");
  534. good("{\"x\":1,\"y\":2, \"z\" :3}");
  535. good("{\"x\":1,\"y\":2, \"z\": 3}");
  536. good("{\"x\":1,\"y\":2, \"z\":3 }");
  537. good(" \t { \"x\" \n : 1, \"y\" :2, \"z\" : 3} \n");
  538. good("[{\"x\":[{\"y\":null}]}]");
  539. bad ("{");
  540. bad (" {");
  541. bad (" {}}");
  542. bad ("{{}}");
  543. bad ("{[]}");
  544. bad (R"jv( {"x";null} )jv");
  545. bad (R"jv( {"x":null . "y":0} )jv");
  546. }
  547. void
  548. testParser()
  549. {
  550. auto const check =
  551. [this]( string_view s,
  552. bool done)
  553. {
  554. fail_parser p;
  555. error_code ec;
  556. p.write_some(
  557. true,
  558. s.data(), s.size(),
  559. ec);
  560. if(! BOOST_TEST(! ec))
  561. {
  562. log << " failed to parse: " << s << '\n';
  563. return;
  564. }
  565. BOOST_TEST(done == p.done());
  566. };
  567. // done()
  568. check("{}", true);
  569. check("{} ", true);
  570. check("{}x", true);
  571. check("{} x", true);
  572. check("[]", true);
  573. check("[] ", true);
  574. check("[]x", true);
  575. check("[] x", true);
  576. check("\"a\"", true);
  577. check("\"a\" ", true);
  578. check("\"a\"x", true);
  579. check("\"a\" x", true);
  580. check("0", false);
  581. check("0 ", true);
  582. check("0x", true);
  583. check("0 x", true);
  584. check("0.", false);
  585. check("0.0", false);
  586. check("0.0 ", true);
  587. check("0.0 x", true);
  588. check("true", true);
  589. check("true ", true);
  590. check("truex", true);
  591. check("true x", true);
  592. check("false", true);
  593. check("false ", true);
  594. check("falsex", true);
  595. check("false x", true);
  596. check("null", true);
  597. check("null ", true);
  598. check("nullx", true);
  599. check("null x", true);
  600. // flush
  601. {
  602. {
  603. for(auto esc :
  604. { "\\\"", "\\\\", "\\/", "\\b",
  605. "\\f", "\\n", "\\r", "\\t", "\\u0000"
  606. })
  607. {
  608. std::string const big =
  609. "\\\"" + std::string(
  610. BOOST_JSON_STACK_BUFFER_SIZE-4, '*') + esc;
  611. std::string const s =
  612. "{\"" + big + "\":\"" + big + "\"}";
  613. good_one(s);
  614. }
  615. }
  616. {
  617. std::string big;
  618. big = "\\\"" +
  619. std::string(
  620. BOOST_JSON_STACK_BUFFER_SIZE+ 1, '*');
  621. std::string s;
  622. s = "{\"" + big + "\":\"" + big + "\"}";
  623. good_one(s);
  624. }
  625. }
  626. // no input
  627. {
  628. error_code ec;
  629. fail_parser p;
  630. p.write(false, nullptr, 0, ec);
  631. BOOST_TEST(ec);
  632. }
  633. }
  634. void
  635. testMembers()
  636. {
  637. fail_parser p;
  638. std::size_t n;
  639. error_code ec;
  640. n = p.write_some(true, "null", 4, ec );
  641. if(BOOST_TEST(! ec))
  642. {
  643. BOOST_TEST(n == 4);
  644. BOOST_TEST(p.done());
  645. n = p.write_some(false, " \t42", 4, ec);
  646. BOOST_TEST(n == 2);
  647. BOOST_TEST(! ec);
  648. }
  649. p.reset();
  650. n = p.write_some(false, "[1,2,3]", 7, ec);
  651. if(BOOST_TEST(! ec))
  652. {
  653. BOOST_TEST(n == 7);
  654. BOOST_TEST(p.done());
  655. }
  656. }
  657. void
  658. testParseVectors()
  659. {
  660. std::vector<parse_options> all_configs =
  661. {
  662. make_options(false, false, true),
  663. make_options(true, false, true),
  664. make_options(false, true, true),
  665. make_options(true, true, true),
  666. make_options(false, false, false),
  667. make_options(true, false, false),
  668. make_options(false, true, false),
  669. make_options(true, true, false)
  670. };
  671. parse_vectors pv;
  672. for(auto const& v : pv)
  673. {
  674. // skip these , because basic_parser
  675. // doesn't have a max_depth setting.
  676. if( v.name == "structure_100000_opening_arrays" ||
  677. v.name == "structure_open_array_object")
  678. {
  679. continue;
  680. }
  681. for (const parse_options& po : all_configs)
  682. {
  683. if(v.result == 'i')
  684. {
  685. error_code ec;
  686. fail_parser p(po);
  687. p.write(
  688. false,
  689. v.text.data(),
  690. v.text.size(),
  691. ec);
  692. if(! ec)
  693. good_one(v.text, po);
  694. else
  695. bad_one(v.text, po);
  696. }
  697. else if(v.result == 'y')
  698. good_one(v.text, po);
  699. else
  700. bad_one(v.text, po);
  701. }
  702. }
  703. }
  704. // https://github.com/boostorg/json/issues/13
  705. void
  706. testIssue13()
  707. {
  708. validate("\"~QQ36644632 {n");
  709. }
  710. void
  711. testIssue20()
  712. {
  713. string_view s =
  714. "WyL//34zOVx1ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlM2M4dWRlMTlcdWQ4M2RcdWRlMzlkZWUzOVx1"
  715. "ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlMzlcXHVkY2M4M1x1ZDg5ZFx1ZGUzOVx1ZDgzZFx1ZGUzOWRb"
  716. "IGZhbHNlLDMzMzMzMzMzMzMzMzMzMzMzNDMzMzMzMTY1MzczNzMwLDMzMzMzMzMzMzMzMzMzMzMz"
  717. "MzM3ODAsMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz"
  718. "MzM3ODAsMzMzMzMzMzMzMzMzMzQzMzMzMzE2NTM3MzczMCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
  719. "LDMzMzMzMzM4MzU1MzMwNzQ3NDYwLDMzMTY2NTAwMDAzMzMzMzMwNzQ3MzMzMzMzMzc3OSwzMzMz"
  720. "MzMzMzMzMzMzMzMzNDMzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMz"
  721. "MzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAs"
  722. "MzMzMzMzMzMxNjY1MDAwMDMzMzMzNDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMz"
  723. "MzMzMzM3MzMzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQz"
  724. "MzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzNzgw"
  725. "LDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3"
  726. "NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
  727. "LDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMzMzMwODgzNTUz"
  728. "MzA3NDM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMzMzMDczMzM3"
  729. "NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
  730. "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0"
  731. "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4"
  732. "MzU1MzMwNzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzMzMzMz"
  733. "MzMzMzM0MjQ3LDMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMzMzMzMzMzM3MzMzMzQzMzMzMzMzMDc0"
  734. "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
  735. "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3"
  736. "NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4"
  737. "MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMzMzMzMzMzLDMzMzMzMzMzMzMzMzMz"
  738. "MzMzMzM3ODAsMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1"
  739. "MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzM3ODAsMzMzMzMzMzgzNTUzMzA3NDc0"
  740. "NjAsMzMxNjY1MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzMz"
  741. "MzA3NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMw"
  742. "NzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzE2NjUwMDAwMzMz"
  743. "MzM0NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3"
  744. "MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAw"
  745. "MzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0NzQ2MCwzMzMz"
  746. "MzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDM3ODAsMzMzMzMz"
  747. "MzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMTY2NTAwMDAzMzMzMzQ3NDYwLDMzMzMz"
  748. "MzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzNzMzMzM0MzMzMzMzMzA3NDc0NjAsMzMzMzMz"
  749. "MzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1MDAwMDMz"
  750. "MzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzNcdWQ4N2RcdWRlZGV1ZGM4"
  751. "ZGUzOVx1ZDg0ZFx1ZGM4M2RcdWQ4OGRcdWRlMzlcdWQ4OWRcdWRlMjM5MzMzZWUzOVxk";
  752. auto const len = base64::decoded_size(s.size());
  753. std::unique_ptr<char[]> p(new char[len]);
  754. base64::decode(
  755. p.get(), s.data(), s.size());
  756. string_view const js(p.get(), len);
  757. BOOST_TEST(! validate(js));
  758. }
  759. void
  760. testIssue113()
  761. {
  762. string_view s =
  763. "\"\\r\\n section id='description'>\\r\\nAll mbers form the uncountable set "
  764. "\\u211D. Among its subsets, relatively simple are the convex sets, each expressed "
  765. "as a range between two real numbers <i>a</i> and <i>b</i> where <i>a</i> \\u2264 <i>"
  766. "b</i>. There are actually four cases for the meaning of \\\"between\\\", depending "
  767. "on open or closed boundary:\\r\\n\\r\\n<ul>\\r\\n <li>[<i>a</i>, <i>b</i>]: {<i>"
  768. "x</i> | <i>a</i> \\u2264 <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n <li>"
  769. "(<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> < <i>x</i> and <i>x</i> < <i>b</i> }"
  770. "</li>\\r\\n <li>[<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> \\u2264 <i>x</i> and "
  771. "<i>x</i> < <i>b</i> }</li>\\r\\n <li>(<i>a</i>, <i>b</i>]: {<i>x</i> | <i>a</i> "
  772. "< <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n</ul>\\r\\n\\r\\nNote that "
  773. "if <i>a</i> = <i>b</i>, of the four only [<i>a</i>, <i>a</i>] would be non-empty."
  774. "\\r\\n\\r\\n<strong>Task</strong>\\r\\n\\r\\n<ul>\\r\\n <li>Devise a way to "
  775. "represent any set of real numbers, for the definition of \\\"any\\\" in the "
  776. "implementation notes below.</li>\\r\\n <li>Provide methods for these common "
  777. "set operations (<i>x</i> is a real number; <i>A</i> and <i>B</i> are sets):</li>"
  778. "\\r\\n <ul>\\r\\n <li>\\r\\n <i>x</i> \\u2208 <i>A</i>: determine if <i>"
  779. "x</i> is an element of <i>A</i><br>\\r\\n example: 1 is in [1, 2), while 2, "
  780. "3, ... are not.\\r\\n </li>\\r\\n <li>\\r\\n <i>A</i> \\u222A <i>B</i>: "
  781. "union of <i>A</i> and <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 <i>A</i> or <i>x"
  782. "</i> \\u2208 <i>B</i>}<br>\\r\\n example: [0, 2) \\u222A (1, 3) = [0, 3); "
  783. "[0, 1) \\u222A (2, 3] = well, [0, 1) \\u222A (2, 3]\\r\\n </li>\\r\\n <li>"
  784. "\\r\\n <i>A</i> \\u2229 <i>B</i>: intersection of <i>A</i> and <i>B</i>, i.e. "
  785. "{<i>x</i> | <i>x</i> \\u2208 <i>A</i> and <i>x</i> \\u2208 <i>B</i>}<br>\\r\\n "
  786. "example: [0, 2) \\u2229 (1, 3) = (1, 2); [0, 1) \\u2229 (2, 3] = empty set\\r\\n "
  787. "</li>\\r\\n <li>\\r\\n <i>A</i> - <i>B</i>: difference between <i>A</i> and "
  788. "<i>B</i>, also written as <i>A</i> \\\\ <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 "
  789. "<i>A</i> and <i>x</i> \\u2209 <i>B</i>}<br>\\r\\n example: [0, 2) \\u2212 (1, "
  790. "3) = [0, 1]\\r\\n </li>\\r\\n </ul>\\r\\n</ul>\\r\\n</section>\\r\\n\"\n";
  791. good_one(s);
  792. }
  793. class comment_parser
  794. {
  795. struct handler
  796. {
  797. constexpr static std::size_t max_object_size = std::size_t(-1);
  798. constexpr static std::size_t max_array_size = std::size_t(-1);
  799. constexpr static std::size_t max_key_size = std::size_t(-1);
  800. constexpr static std::size_t max_string_size = std::size_t(-1);
  801. std::string captured = "";
  802. bool on_document_begin( error_code& ) { return true; }
  803. bool on_document_end( error_code& ) { return true; }
  804. bool on_object_begin( error_code& ) { return true; }
  805. bool on_object_end( std::size_t, error_code& ) { return true; }
  806. bool on_array_begin( error_code& ) { return true; }
  807. bool on_array_end( std::size_t, error_code& ) { return true; }
  808. bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
  809. bool on_key( string_view, std::size_t, error_code& ) { return true; }
  810. bool on_string_part( string_view, std::size_t, error_code& ) { return true; }
  811. bool on_string( string_view, std::size_t, error_code& ) { return true; }
  812. bool on_number_part( string_view, error_code&) { return true; }
  813. bool on_int64( std::int64_t, string_view, error_code& ) { return true; }
  814. bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; }
  815. bool on_double( double, string_view, error_code& ) { return true; }
  816. bool on_bool( bool, error_code& ) { return true; }
  817. bool on_null( error_code& ) { return true; }
  818. bool on_comment_part( string_view s, error_code& )
  819. {
  820. captured.append(s.data(), s.size());
  821. return true;
  822. }
  823. bool on_comment( string_view s, error_code& )
  824. {
  825. captured.append(s.data(), s.size());
  826. return true;
  827. }
  828. };
  829. basic_parser<handler> p_;
  830. public:
  831. comment_parser()
  832. : p_(make_options(true, false, false))
  833. {
  834. }
  835. std::size_t
  836. write(
  837. char const* data,
  838. std::size_t size,
  839. error_code& ec)
  840. {
  841. auto const n = p_.write_some(
  842. false, data, size, ec);
  843. if(! ec && n < size)
  844. ec = error::extra_data;
  845. return n;
  846. }
  847. string_view
  848. captured() const noexcept
  849. {
  850. return p_.handler().captured;
  851. }
  852. };
  853. void
  854. testComments()
  855. {
  856. parse_options disabled;
  857. parse_options enabled;
  858. enabled.allow_comments = true;
  859. const auto replace_and_test =
  860. [&](string_view s)
  861. {
  862. static std::vector<string_view> comments =
  863. {
  864. "//\n",
  865. "// \n",
  866. "//aaaa\n",
  867. "// aaaa\n",
  868. "// /* \n",
  869. "// /**/ \n",
  870. "/**/",
  871. "/*//*/",
  872. "/*/*/",
  873. "/******/",
  874. "/*** ***/",
  875. "/**aaaa***/",
  876. "/*** aaaa***/"
  877. };
  878. std::string formatted = "";
  879. std::string just_comments = "";
  880. std::size_t guess = std::count(
  881. s.begin(), s.end(), '@') * 12;
  882. formatted.reserve(guess + s.size());
  883. just_comments.reserve(guess);
  884. std::size_t n = 0;
  885. for (char c : s)
  886. {
  887. if (c == '@')
  888. {
  889. string_view com =
  890. comments[((formatted.size() + n) % s.size()) % comments.size()];
  891. formatted.append(com.data(), n = com.size());
  892. just_comments.append(com.data(), com.size());
  893. continue;
  894. }
  895. formatted += c;
  896. }
  897. bad(formatted, disabled);
  898. good(formatted, enabled);
  899. {
  900. // test the handler
  901. comment_parser p;
  902. error_code ec;
  903. p.write( formatted.data(), formatted.size(), ec );
  904. BOOST_TEST(! ec);
  905. BOOST_TEST(p.captured() == just_comments);
  906. }
  907. };
  908. replace_and_test("@1");
  909. replace_and_test("1@");
  910. replace_and_test("@1@");
  911. replace_and_test("[@1]");
  912. replace_and_test("[1@]");
  913. replace_and_test("[1,2@]");
  914. replace_and_test("[1,@2]");
  915. replace_and_test("[1@,2]");
  916. replace_and_test("@[@1@,@2@]@");
  917. replace_and_test("{@\"a\":1}");
  918. replace_and_test("{\"a\"@:1}");
  919. replace_and_test("{\"a\":1@}");
  920. replace_and_test("{\"a\":1@,\"b\":2}");
  921. replace_and_test("{\"a\":1,@\"b\":2}");
  922. replace_and_test("@{@\"a\"@:@1@,@\"b\"@:@2@}");
  923. // no following token
  924. bad("1/", enabled);
  925. // bad second token
  926. bad("1/x", enabled);
  927. // no comment close
  928. bad("1/*", enabled);
  929. bad("1/**", enabled);
  930. bad("[1 //, 2]", enabled);
  931. // just comment
  932. bad("//\n", enabled);
  933. bad("//", enabled);
  934. bad("/**/", enabled);
  935. // no newline at EOF
  936. good("1//", enabled);
  937. }
  938. void
  939. testAllowTrailing()
  940. {
  941. parse_options disabled;
  942. parse_options enabled;
  943. enabled.allow_trailing_commas = true;
  944. bad("[1,]", disabled);
  945. good("[1,]", enabled);
  946. bad("[1,[],]", disabled);
  947. good("[1,[],]", enabled);
  948. bad("[1,{},]", disabled);
  949. good("[1,{},]", enabled);
  950. bad("[1,{\"a\":1,},]", disabled);
  951. good("[1,{\"a\":1,},]", enabled);
  952. bad("{\"a\":1,}", disabled);
  953. good("{\"a\":1,}", enabled);
  954. bad("{\"a\":[1,],}", disabled);
  955. good("{\"a\":[1,],}", enabled);
  956. bad("{\"a\":[],}", disabled);
  957. good("{\"a\":[],}", enabled);
  958. bad("{\"a\":[{}, [1,]],}", disabled);
  959. good("{\"a\":[{}, [1,]],}", enabled);
  960. bad("[[[[[[[],],],],],],]", disabled);
  961. good("[[[[[[[],],],],],],]", enabled);
  962. bad("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", disabled);
  963. good("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", enabled);
  964. }
  965. class utf8_parser
  966. {
  967. struct handler
  968. {
  969. constexpr static std::size_t max_object_size = std::size_t(-1);
  970. constexpr static std::size_t max_array_size = std::size_t(-1);
  971. constexpr static std::size_t max_key_size = std::size_t(-1);
  972. constexpr static std::size_t max_string_size = std::size_t(-1);
  973. std::string captured = "";
  974. bool on_document_begin( error_code& ) { return true; }
  975. bool on_document_end( error_code& ) { return true; }
  976. bool on_object_begin( error_code& ) { return true; }
  977. bool on_object_end( std::size_t, error_code& ) { return true; }
  978. bool on_array_begin( error_code& ) { return true; }
  979. bool on_array_end( std::size_t, error_code& ) { return true; }
  980. bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
  981. bool on_key( string_view, std::size_t, error_code& ) { return true; }
  982. bool on_string_part( string_view sv, std::size_t, error_code& )
  983. {
  984. captured.append(sv.data(), sv.size());
  985. return true;
  986. }
  987. bool on_string( string_view sv, std::size_t, error_code& )
  988. {
  989. captured.append(sv.data(), sv.size());
  990. return true;
  991. }
  992. bool on_number_part( string_view, error_code&) { return true; }
  993. bool on_int64( std::int64_t, string_view, error_code& ) { return true; }
  994. bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; }
  995. bool on_double( double, string_view, error_code& ) { return true; }
  996. bool on_bool( bool, error_code& ) { return true; }
  997. bool on_null( error_code& ) { return true; }
  998. bool on_comment_part( string_view, error_code& ) { return true; }
  999. bool on_comment( string_view, error_code& ) { return true; }
  1000. };
  1001. basic_parser<handler> p_;
  1002. public:
  1003. utf8_parser()
  1004. : p_(parse_options())
  1005. {
  1006. }
  1007. std::size_t
  1008. write(
  1009. bool more,
  1010. char const* data,
  1011. std::size_t size,
  1012. error_code& ec)
  1013. {
  1014. auto const n = p_.write_some(
  1015. more, data, size, ec);
  1016. if(! ec && n < size)
  1017. ec = error::extra_data;
  1018. return n;
  1019. }
  1020. string_view
  1021. captured() const noexcept
  1022. {
  1023. return p_.handler().captured;
  1024. }
  1025. };
  1026. void
  1027. testUTF8Validation()
  1028. {
  1029. good("\"\xc2\x80----------\"");
  1030. good("\"\xc2\xbf----------\"");
  1031. good("\"\xdf\x80----------\"");
  1032. good("\"\xdf\xbf----------\"");
  1033. good("\"\xcf\x90----------\"");
  1034. good("\"\xe0\xa0\x80----------\"");
  1035. good("\"\xe0\xa0\xbf----------\"");
  1036. good("\"\xe0\xbf\x80----------\"");
  1037. good("\"\xe0\xbf\xbf----------\"");
  1038. good("\"\xe0\xb0\x90----------\"");
  1039. good("\"\xe1\x80\x80----------\"");
  1040. good("\"\xe1\xbf\x80----------\"");
  1041. good("\"\xec\x80\x80----------\"");
  1042. good("\"\xec\xbf\x80----------\"");
  1043. good("\"\xe1\x80\xbf----------\"");
  1044. good("\"\xe1\xbf\xbf----------\"");
  1045. good("\"\xec\x80\xbf----------\"");
  1046. good("\"\xec\xbf\xbf----------\"");
  1047. good("\"\xe6\x90\x90----------\"");
  1048. good("\"\xed\x80\x80----------\"");
  1049. good("\"\xed\x80\xbf----------\"");
  1050. good("\"\xed\x9f\x80----------\"");
  1051. good("\"\xed\x9f\xbf----------\"");
  1052. good("\"\xed\x90\x90----------\"");
  1053. good("\"\xee\x80\x80----------\"");
  1054. good("\"\xee\xbf\x80----------\"");
  1055. good("\"\xef\x80\x80----------\"");
  1056. good("\"\xef\xbf\x80----------\"");
  1057. good("\"\xee\x80\xbf----------\"");
  1058. good("\"\xee\xbf\xbf----------\"");
  1059. good("\"\xef\x80\xbf----------\"");
  1060. good("\"\xef\xbf\xbf----------\"");
  1061. good("\"\xee\x90\x90----------\"");
  1062. good("\"\xef\x90\x90----------\"");
  1063. good("\"\xf0\x90\x80\x80----------\"");
  1064. good("\"\xf0\x90\xbf\x80----------\"");
  1065. good("\"\xf0\x90\xbf\xbf----------\"");
  1066. good("\"\xf0\x90\x80\xbf----------\"");
  1067. good("\"\xf0\xbf\x80\x80----------\"");
  1068. good("\"\xf0\xbf\xbf\x80----------\"");
  1069. good("\"\xf0\xbf\xbf\xbf----------\"");
  1070. good("\"\xf0\xbf\x80\xbf----------\"");
  1071. good("\"\xf0\xA0\x90\x90----------\"");
  1072. good("\"\xf4\x80\x80\x80----------\"");
  1073. good("\"\xf4\x80\xbf\x80----------\"");
  1074. good("\"\xf4\x80\xbf\xbf----------\"");
  1075. good("\"\xf4\x80\x80\xbf----------\"");
  1076. good("\"\xf4\x8f\x80\x80----------\"");
  1077. good("\"\xf4\x8f\xbf\x80----------\"");
  1078. good("\"\xf4\x8f\xbf\xbf----------\"");
  1079. good("\"\xf4\x8f\x80\xbf----------\"");
  1080. good("\"\xf4\x88\x90\x90----------\"");
  1081. good("\"\xf1\x80\x80\x80----------\"");
  1082. good("\"\xf1\x80\xbf\x80----------\"");
  1083. good("\"\xf1\x80\xbf\xbf----------\"");
  1084. good("\"\xf1\x80\x80\xbf----------\"");
  1085. good("\"\xf1\xbf\x80\x80----------\"");
  1086. good("\"\xf1\xbf\xbf\x80----------\"");
  1087. good("\"\xf1\xbf\xbf\xbf----------\"");
  1088. good("\"\xf1\xbf\x80\xbf----------\"");
  1089. good("\"\xf3\x80\x80\x80----------\"");
  1090. good("\"\xf3\x80\xbf\x80----------\"");
  1091. good("\"\xf3\x80\xbf\xbf----------\"");
  1092. good("\"\xf3\x80\x80\xbf----------\"");
  1093. good("\"\xf3\xbf\x80\x80----------\"");
  1094. good("\"\xf3\xbf\xbf\x80----------\"");
  1095. good("\"\xf3\xbf\xbf\xbf----------\"");
  1096. good("\"\xf3\xbf\x80\xbf----------\"");
  1097. good("\"\xf2\x90\x90\x90----------\"");
  1098. bad("\"\xc0\x80----------\"");
  1099. bad("\"\xc2\xc0----------\"");
  1100. bad("\"\xef\x80----------\"");
  1101. bad("\"\xdf\x70----------\"");
  1102. bad("\"\xff\x90----------\"");
  1103. bad("\"\xe0\x9f\x80----------\"");
  1104. bad("\"\xe0\xa0\xfe----------\"");
  1105. bad("\"\xc0\xff\xff----------\"");
  1106. bad("\"\xc0\xbf\x76----------\"");
  1107. bad("\"\xe0\xde\x90----------\"");
  1108. bad("\"\xe1\x80\x7f----------\"");
  1109. bad("\"\xe1\x7f\x80----------\"");
  1110. bad("\"\xec\xff\x80----------\"");
  1111. bad("\"\xef\x7f\x80----------\"");
  1112. bad("\"\xe1\x80\xff----------\"");
  1113. bad("\"\xe1\xbf\x0f----------\"");
  1114. bad("\"\xec\x01\xff----------\"");
  1115. bad("\"\xec\xff\xff----------\"");
  1116. bad("\"\xe6\x60\x90----------\"");
  1117. bad("\"\xed\x7f\x80----------\"");
  1118. bad("\"\xed\xa0\xbf----------\"");
  1119. bad("\"\xed\xbf\x80----------\"");
  1120. bad("\"\xed\x9f\x7f----------\"");
  1121. bad("\"\xed\xce\xbf----------\"");
  1122. bad("\"\xee\x7f\x80----------\"");
  1123. bad("\"\xee\xcc\x80----------\"");
  1124. bad("\"\xef\x80\xcc----------\"");
  1125. bad("\"\xef\xbf\x0a----------\"");
  1126. bad("\"\xee\x50\xbf----------\"");
  1127. bad("\"\xee\xef\xbf----------\"");
  1128. bad("\"\xef\xf0\xff----------\"");
  1129. bad("\"\xef\xaa\xee----------\"");
  1130. bad("\"\xc0\x90\x90----------\"");
  1131. bad("\"\xc1\x90\x90----------\"");
  1132. bad("\"\xff\x90\x80\x80----------\"");
  1133. bad("\"\xfe\x90\xbf\x80----------\"");
  1134. bad("\"\xfd\x90\xbf\xbf----------\"");
  1135. bad("\"\xf0\xff\x80\xbf----------\"");
  1136. bad("\"\xf0\xfe\x80\x80----------\"");
  1137. bad("\"\xf0\xfd\xbf\x80----------\"");
  1138. bad("\"\xf0\x90\x80\xff----------\"");
  1139. bad("\"\xf0\x90\x5f\x80----------\"");
  1140. bad("\"\xf4\x70\x80\x80----------\"");
  1141. bad("\"\xf4\x80\x70\x80----------\"");
  1142. bad("\"\xf4\x80\xbf\x70----------\"");
  1143. bad("\"\xf4\xce\x80\xbf----------\"");
  1144. bad("\"\xf4\x8f\xce\x80----------\"");
  1145. bad("\"\xf4\x8f\xbf\xce----------\"");
  1146. bad("\"\xf1\x7f\xbf\xbf----------\"");
  1147. bad("\"\xf2\x80\x7f\xbf----------\"");
  1148. bad("\"\xf3\x80\xbf\xce----------\"");
  1149. // utf8 after escape
  1150. good("\"\\u0000 \xf3\xbf\x80\xbf\xf3\xbf\x80\xbf\"");
  1151. good("\"\\ud7ff\xf4\x80\xbf\xbf \"");
  1152. good("\"\\ue000 \xef\xbf\x80\"");
  1153. good("\"\xef\xbf\x80 \\uffff \xef\xbf\x80\"");
  1154. good("\"\xc2\x80\xc2\x80\xc2\x80\xc2\x80\xc2\x80\\ud800\\udc00 \"");
  1155. good("\"\\udbff\\udfff \xe1\x80\xbf \\udbff\\udfff \xe1\x80\xbf\"");
  1156. good("\"\\u0000\xe1\x80\xbf \"");
  1157. bad("\"\\t\\t\xf4\x70\x80\x80----------\"");
  1158. bad("\"\\n\xf4\x80\x70\x80----------\"");
  1159. bad("\"\\n\xf4\x80\xbf\x70-\\n\xf4\x80\xbf\x70\"");
  1160. const auto check =
  1161. [this](string_view expected)
  1162. {
  1163. good(expected);
  1164. for (std::size_t write_size : {2, 4, 8})
  1165. {
  1166. utf8_parser p;
  1167. for(std::size_t i = 0; i < expected.size(); i += write_size)
  1168. {
  1169. error_code ec;
  1170. write_size = (std::min)(write_size, expected.size() - i);
  1171. auto more = (i < expected.size() - write_size);
  1172. auto written = p.write(more,
  1173. expected.data() + i, write_size, ec);
  1174. BOOST_TEST(written == write_size);
  1175. BOOST_TEST(! ec);
  1176. }
  1177. BOOST_TEST(p.captured() ==
  1178. expected.substr(1, expected.size() - 2));
  1179. }
  1180. };
  1181. check("\"\xd1\x82\"");
  1182. check("\"\xd1\x82\xd0\xb5\xd1\x81\xd1\x82\"");
  1183. check("\"\xc3\x0b1""and\xc3\xba\"");
  1184. }
  1185. void
  1186. testMaxDepth()
  1187. {
  1188. {
  1189. string_view s = "[[[[[]]]]]";
  1190. parse_options opt;
  1191. opt.max_depth = 4;
  1192. null_parser p(opt);
  1193. error_code ec;
  1194. p.write(s.data(), s.size(), ec);
  1195. BOOST_TEST(ec == error::too_deep);
  1196. }
  1197. {
  1198. string_view s = "[[[[]]], [[[[]]]]]";
  1199. parse_options opt;
  1200. opt.max_depth = 4;
  1201. null_parser p(opt);
  1202. error_code ec;
  1203. p.write(s.data(), s.size(), ec);
  1204. BOOST_TEST(ec == error::too_deep);
  1205. }
  1206. {
  1207. string_view s =
  1208. "{\"a\":{\"b\":{\"c\":{}}},\"b\":{\"c\":{\"d\":{\"e\":{}}}}}";
  1209. parse_options opt;
  1210. opt.max_depth = 4;
  1211. null_parser p(opt);
  1212. error_code ec;
  1213. p.write(s.data(), s.size(), ec);
  1214. BOOST_TEST(ec == error::too_deep);
  1215. }
  1216. {
  1217. string_view s =
  1218. "{\"a\":{\"b\":{\"c\":{\"d\":{}}}}}";
  1219. parse_options opt;
  1220. opt.max_depth = 4;
  1221. null_parser p(opt);
  1222. error_code ec;
  1223. p.write(s.data(), s.size(), ec);
  1224. BOOST_TEST(ec == error::too_deep);
  1225. }
  1226. }
  1227. class literal_parser
  1228. {
  1229. struct handler
  1230. {
  1231. constexpr static std::size_t max_object_size = std::size_t(-1);
  1232. constexpr static std::size_t max_array_size = std::size_t(-1);
  1233. constexpr static std::size_t max_key_size = std::size_t(-1);
  1234. constexpr static std::size_t max_string_size = std::size_t(-1);
  1235. std::string captured = "";
  1236. bool on_document_begin( error_code& ) { return true; }
  1237. bool on_document_end( error_code& ) { return true; }
  1238. bool on_object_begin( error_code& ) { return true; }
  1239. bool on_object_end( std::size_t, error_code& ) { return true; }
  1240. bool on_array_begin( error_code& ) { return true; }
  1241. bool on_array_end( std::size_t, error_code& ) { return true; }
  1242. bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
  1243. bool on_key( string_view, std::size_t, error_code& ) { return true; }
  1244. bool on_string_part( string_view, std::size_t, error_code& ) { return true; }
  1245. bool on_string( string_view, std::size_t, error_code& ) { return true; }
  1246. bool on_number_part( string_view sv, error_code&)
  1247. {
  1248. captured.append(sv.data(), sv.size());
  1249. return true;
  1250. }
  1251. bool on_int64( std::int64_t, string_view sv, error_code& )
  1252. {
  1253. captured.append(sv.data(), sv.size());
  1254. captured += 's';
  1255. return true;
  1256. }
  1257. bool on_uint64( std::uint64_t, string_view sv, error_code& )
  1258. {
  1259. captured.append(sv.data(), sv.size());
  1260. captured += 'u';
  1261. return true;
  1262. }
  1263. bool on_double( double, string_view sv, error_code& )
  1264. {
  1265. captured.append(sv.data(), sv.size());
  1266. captured += 'd';
  1267. return true;
  1268. }
  1269. bool on_bool( bool, error_code& ) { return true; }
  1270. bool on_null( error_code& ) { return true; }
  1271. bool on_comment_part( string_view, error_code& ) { return true; }
  1272. bool on_comment( string_view, error_code& ) { return true; }
  1273. };
  1274. basic_parser<handler> p_;
  1275. public:
  1276. literal_parser()
  1277. : p_(make_options(true, false, false))
  1278. {
  1279. }
  1280. std::size_t
  1281. write(
  1282. bool more,
  1283. char const* data,
  1284. std::size_t size,
  1285. error_code& ec)
  1286. {
  1287. auto const n = p_.write_some(
  1288. more, data, size, ec);
  1289. if(! ec && n < size)
  1290. ec = error::extra_data;
  1291. return n;
  1292. }
  1293. string_view
  1294. captured()
  1295. {
  1296. return p_.handler().captured;
  1297. }
  1298. };
  1299. void
  1300. testNumberLiteral()
  1301. {
  1302. const auto check =
  1303. [](string_view expected)
  1304. {
  1305. string_view sv = expected;
  1306. sv.remove_suffix(1);
  1307. for(std::size_t i = 0;
  1308. i < sv.size(); ++i)
  1309. {
  1310. literal_parser p;
  1311. error_code ec;
  1312. if(i != 0)
  1313. {
  1314. p.write(true,
  1315. sv.data(), i, ec);
  1316. }
  1317. if(BOOST_TEST(! ec))
  1318. {
  1319. p.write(false,
  1320. sv.data() + i,
  1321. sv.size() - i, ec);
  1322. }
  1323. BOOST_TEST(! ec);
  1324. BOOST_TEST(p.captured() == expected);
  1325. }
  1326. };
  1327. check("1s");
  1328. check("-1s");
  1329. check("0s");
  1330. check("0s");
  1331. check("123456s");
  1332. check("-123456s");
  1333. check("9223372036854775808u");
  1334. check("1.0d");
  1335. check("-