2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
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)
8 // Official repository: https://github.com/boostorg/json
11 // Test that header file is self-contained.
12 #include <boost/json/basic_parser_impl.hpp>
18 #include "parse-vectors.hpp"
20 #include "test_suite.hpp"
24 BOOST_STATIC_ASSERT( std::is_nothrow_destructible
<basic_parser
<int>>::value
);
29 decoded_size(std::size_t n
)
31 return n
/ 4 * 3; // requires n&3==0, smaller
37 static signed char constexpr tab
[] = {
38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
39 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
41 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
42 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
43 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
44 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
45 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
48 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
50 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
58 std::pair
<std::size_t, std::size_t>
59 decode(void* dest
, char const* src
, std::size_t len
)
61 char* out
= static_cast<char*>(dest
);
62 auto in
= reinterpret_cast<unsigned char const*>(src
);
63 unsigned char c3
[3], c4
[4];
67 auto const inverse
= base64::get_inverse();
69 while(len
-- && *in
!= '=')
71 auto const v
= inverse
[*in
];
78 c3
[0] = (c4
[0] << 2) + ((c4
[1] & 0x30) >> 4);
79 c3
[1] = ((c4
[1] & 0xf) << 4) + ((c4
[2] & 0x3c) >> 2);
80 c3
[2] = ((c4
[2] & 0x3) << 6) + c4
[3];
82 for(i
= 0; i
< 3; i
++)
90 c3
[0] = ( c4
[0] << 2) + ((c4
[1] & 0x30) >> 4);
91 c3
[1] = ((c4
[1] & 0xf) << 4) + ((c4
[2] & 0x3c) >> 2);
92 c3
[2] = ((c4
[2] & 0x3) << 6) + c4
[3];
94 for(j
= 0; j
< i
- 1; j
++)
98 return {out
- static_cast<char*>(dest
),
99 in
- reinterpret_cast<unsigned char const*>(src
)};
107 validate( string_view s
)
109 // Parse with the null parser and return false on error
112 p
.write( s
.data(), s
.size(), ec
);
116 // The string is valid JSON.
127 opt
.allow_comments
= comments
;
128 opt
.allow_trailing_commas
= commas
;
129 opt
.allow_invalid_utf8
= utf8
;
135 class basic_parser_test
138 ::test_suite::log_type log
;
149 s
.data(), s
.size(), ec
);
150 BOOST_TEST((good
&& !ec
) ||
158 const std::vector
<parse_options
>& configs
)
160 for (const parse_options
& po
: configs
)
161 grind_one(s
, good
, po
);
170 grind_one(s
, good
, po
);
172 // split/errors matrix
175 for(std::size_t i
= 1;
178 for(std::size_t j
= 1;;++j
)
181 fail_parser
p(j
, po
);
182 p
.write(true, s
.data(), i
, ec
);
183 if(ec
== error::test_failure
)
187 p
.write(false, s
.data() + i
,
189 if(ec
== error::test_failure
)
192 BOOST_TEST((good
&& !ec
) || (
199 // split/exceptions matrix
202 for(std::size_t i
= 1;
205 for(std::size_t j
= 1;;++j
)
208 throw_parser
p(j
, po
);
212 true, s
.data(), i
, ec
);
217 BOOST_TEST((good
&& !ec
) || (
221 catch(test_exception
const&)
225 catch(std::exception
const& e
)
229 e
.what() << std::endl
;
240 const std::vector
<parse_options
>& configs
)
242 for (const parse_options
& po
: configs
)
249 grind(s
, false, parse_options());
255 grind(s
, true, parse_options());
261 const parse_options
& po
)
269 const parse_options
& po
)
277 const parse_options
& po
)
279 grind_one(s
, false, po
);
285 const parse_options
& po
)
287 grind_one(s
, true, po
);
291 bad_one(string_view s
)
293 grind_one(s
, false, parse_options());
297 good_one(string_view s
)
299 grind_one(s
, true, parse_options());
302 //------------------------------------------------------
312 good("\r\n\t null\r\n\t ");
334 good("\r\n\t true\r\n\t ");
351 good("\r\n\t false\r\n\t ");
369 good(R
"jv( "x
" )jv");
370 good(R
"jv( "xy
" )jv");
371 good(R
"jv( "x y
" )jv");
374 good(R
"jv(" \" ")jv");
375 good(R
"jv(" \\ ")jv");
376 good(R
"jv(" \
/ ")jv");
377 good(R
"jv(" \b ")jv");
378 good(R
"jv(" \f ")jv");
379 good(R
"jv(" \n ")jv");
380 good(R
"jv(" \r ")jv");
381 good(R
"jv(" \t ")jv");
384 good(R
"jv( " \u0000 " )jv");
385 good(R
"jv( " \ud7ff " )jv");
386 good(R
"jv( " \ue000 " )jv");
387 good(R
"jv( " \uffff " )jv");
388 good(R
"jv( " \ud800\udc00 " )jv");
389 good(R
"jv( " \udbff\udfff " )jv");
390 good(R
"jv( " \n\u0000 " )jv");
393 good(R
"jv( {" \n":null} )jv");
398 // illegal control character
399 bad ({ "\"" "\x00" "\"", 3 });
400 bad ("\"" "\x1f" "\"");
401 bad ("\"" "\\n" "\x1f" "\"");
404 bad (R
"jv( "\" )jv
");
407 bad (R"jv( "\z" )jv
");
409 // utf-16 escape, fast path,
411 bad (R"jv( " \u---- " )jv
");
412 bad (R"jv( " \ud--- " )jv
");
413 bad (R"jv( " \ud8-- " )jv
");
414 bad (R"jv( " \ud80- " )jv
");
415 // invalid low surrogate
416 bad (R"jv( " \ud800------ " )jv
");
417 bad (R"jv( " \ud800\----- " )jv
");
418 bad (R"jv( " \ud800\u---- " )jv
");
419 bad (R"jv( " \ud800\ud--- " )jv
");
420 bad (R"jv( " \ud800\udc-- " )jv
");
421 bad (R"jv( " \ud800\udc0- " )jv
");
422 // illegal leading surrogate
423 bad (R"jv( " \udc00 " )jv
");
424 bad (R"jv( " \udfff " )jv
");
425 // illegal trailing surrogate
426 bad (R"jv( " \ud800\udbff " )jv
");
427 bad (R"jv( " \ud800\ue000 " )jv
");
490 good("9223372036854775807 ");
491 good("-9223372036854775807 ");
492 good("18446744073709551615 ");
493 good("-18446744073709551615 ");
495 good("1234567890123456");
496 good("-1234567890123456");
497 good("10000000000000000000000000");
499 good("0.900719925474099178 ");
501 // non-significant digits
502 good("1000000000000000000000000 ");
503 good("1000000000000000000000000e1
");
504 good("1000000000000000000000000.0 ");
505 good("1000000000000000000000000.00 ");
506 good("1000000000000000000000000.000000000001");
507 good("1000000000000000000000000.0e1
");
508 good("1000000000000000000000000.0 ");
510 good("1000000000.1000000000 ");
533 bad("1000000000000000000000000.e
");
536 bad("0.0e2147483648
");
548 good("[ \"x
\", \"y
\" ]");
560 good(" [ 1 , 2 \t\n , \n3]");
566 bad (R"jv( [ null
; 1 ] )jv
");
575 good("{\"x
\":null
}");
576 good("{ \"x
\":null
}");
577 good("{\"x
\" :null
}");
578 good("{\"x
\": null
}");
579 good("{\"x
\":null
}");
580 good("{ \"x
\" : null
}");
581 good("{ \"x
\" : {} }");
582 good("{ \"x
\" : [] }");
583 good("{ \"x
\" : { \"y
\" : null
} }");
584 good("{ \"x
\" : [{}] }");
585 good("{\"x
\\ny
\\u0022
\":null
}");
586 good("{ \"x
\":1, \"y
\":null
}");
587 good("{\"x
\":1,\"y
\":2,\"z
\":3}");
588 good(" {\"x
\":1,\"y
\":2,\"z
\":3}");
589 good("{\"x
\":1,\"y
\":2,\"z
\":3} ");
590 good(" {\"x
\":1,\"y
\":2,\"z
\":3} ");
591 good("{ \"x
\":1,\"y
\":2,\"z
\":3}");
592 good("{\"x
\" :1,\"y
\":2,\"z
\":3}");
593 good("{\"x
\":1 ,\"y
\":2,\"z
\":3}");
594 good("{\"x
\":1,\"y
\" :2,\"z
\":3}");
595 good("{\"x
\":1,\"y
\": 2,\"z
\":3}");
596 good("{\"x
\":1,\"y
\":2 ,\"z
\":3}");
597 good("{\"x
\":1,\"y
\":2, \"z
\":3}");
598 good("{\"x
\":1,\"y
\":2, \"z
\" :3}");
599 good("{\"x
\":1,\"y
\":2, \"z
\": 3}");
600 good("{\"x
\":1,\"y
\":2, \"z
\":3 }");
601 good(" \t { \"x
\" \n : 1, \"y
\" :2, \"z
\" : 3} \n");
603 good("[{\"x
\":[{\"y
\":null
}]}]");
611 bad (R"jv( {"x";null
} )jv
");
612 bad (R"jv( {"x":null
. "y":0} )jv
");
619 [this]( string_view s,
628 if(! BOOST_TEST(! ec))
630 log << " failed to parse
: " << s << '\n';
633 BOOST_TEST(done == p.done());
648 check("\"a
\"", true);
649 check("\"a
\" ", true);
650 check("\"a
\"x
", true);
651 check("\"a
\" x
", true);
660 check("0.0 x
", true);
663 check("true ", true);
664 check("truex
", true);
665 check("true x
", true);
667 check("false", true);
668 check("false ", true);
669 check("falsex
", true);
670 check("false x
", true);
673 check("null
", true);
674 check("nullx
", true);
675 check("null x
", true);
681 { "\\\"", "\\\\", "\\/", "\\b
",
682 "\\f
", "\\n
", "\\r
", "\\t
", "\\u0000
"
685 std::string const big =
686 "\\\"" + std::string(
687 BOOST_JSON_STACK_BUFFER_SIZE-4, '*') + esc;
688 std::string const s =
689 "{\"" + big + "\":\"" + big + "\"}";
697 BOOST_JSON_STACK_BUFFER_SIZE+ 1, '*');
699 s = "{\"" + big + "\":\"" + big + "\"}";
708 p.write(false, nullptr, 0, ec);
719 n = p.write_some(true, "null
", 4, ec );
723 BOOST_TEST(p.done());
724 n = p.write_some(false, " \t42", 4, ec);
729 n = p.write_some(false, "[1,2,3]", 7, ec);
733 BOOST_TEST(p.done());
740 std::vector<parse_options> all_configs =
742 make_options(false, false, true),
743 make_options(true, false, true),
744 make_options(false, true, true),
745 make_options(true, true, true),
746 make_options(false, false, false),
747 make_options(true, false, false),
748 make_options(false, true, false),
749 make_options(true, true, false)
752 for(auto const& v : pv)
754 // skip these , because basic_parser
755 // doesn't have a max_depth setting.
756 if( v.name == "structure_100000_opening_arrays
" ||
757 v.name == "structure_open_array_object
")
761 for (const parse_options& po : all_configs)
773 good_one(v.text, po);
777 else if(v.result == 'y')
778 good_one(v.text, po);
785 // https://github.com/boostorg/json/issues/13
789 validate("\"~QQ36644632
{n
");
796 "WyL
//34zOVx1ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlM2M4dWRlMTlcdWQ4M2RcdWRlMzlkZWUzOVx1"
797 "ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlMzlcXHVkY2M4M1x1ZDg5ZFx1ZGUzOVx1ZDgzZFx1ZGUzOWRb"
798 "IGZhbHNlLDMzMzMzMzMzMzMzMzMzMzMzNDMzMzMzMTY1MzczNzMwLDMzMzMzMzMzMzMzMzMzMzMz"
799 "MzM3ODAsMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz"
800 "MzM3ODAsMzMzMzMzMzMzMzMzMzQzMzMzMzE2NTM3MzczMCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
801 "LDMzMzMzMzM4MzU1MzMwNzQ3NDYwLDMzMTY2NTAwMDAzMzMzMzMwNzQ3MzMzMzMzMzc3OSwzMzMz"
802 "MzMzMzMzMzMzMzMzNDMzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMz"
803 "MzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAs"
804 "MzMzMzMzMzMxNjY1MDAwMDMzMzMzNDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMz"
805 "MzMzMzM3MzMzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQz"
806 "MzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzNzgw"
807 "LDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3"
808 "NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
809 "LDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMzMzMwODgzNTUz"
810 "MzA3NDM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMzMzMDczMzM3"
811 "NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
812 "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0"
813 "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4"
814 "MzU1MzMwNzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzMzMzMz"
815 "MzMzMzM0MjQ3LDMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMzMzMzMzMzM3MzMzMzQzMzMzMzMzMDc0"
816 "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
817 "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3"
818 "NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4"
819 "MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMzMzMzMzMzLDMzMzMzMzMzMzMzMzMz"
820 "MzMzMzM3ODAsMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1"
821 "MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzM3ODAsMzMzMzMzMzgzNTUzMzA3NDc0"
822 "NjAsMzMxNjY1MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzMz"
823 "MzA3NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMw"
824 "NzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzE2NjUwMDAwMzMz"
825 "MzM0NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3"
826 "MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAw"
827 "MzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0NzQ2MCwzMzMz"
828 "MzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDM3ODAsMzMzMzMz"
829 "MzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMTY2NTAwMDAzMzMzMzQ3NDYwLDMzMzMz"
830 "MzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzNzMzMzM0MzMzMzMzMzA3NDc0NjAsMzMzMzMz"
831 "MzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1MDAwMDMz"
832 "MzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzNcdWQ4N2RcdWRlZGV1ZGM4"
833 "ZGUzOVx1ZDg0ZFx1ZGM4M2RcdWQ4OGRcdWRlMzlcdWQ4OWRcdWRlMjM5MzMzZWUzOVxk";
834 auto const len
= base64::decoded_size(s
.size());
835 std::unique_ptr
<char[]> p(new char[len
]);
837 p
.get(), s
.data(), s
.size());
838 string_view
const js(p
.get(), len
);
839 BOOST_TEST(! validate(js
));
846 "\"\\r\\n section id='description'>\\r\\nAll mbers form the uncountable set "
847 "\\u211D. Among its subsets, relatively simple are the convex sets, each expressed "
848 "as a range between two real numbers <i>a</i> and <i>b</i> where <i>a</i> \\u2264 <i>"
849 "b</i>. There are actually four cases for the meaning of \\\"between\\\", depending "
850 "on open or closed boundary:\\r\\n\\r\\n<ul>\\r\\n <li>[<i>a</i>, <i>b</i>]: {<i>"
851 "x</i> | <i>a</i> \\u2264 <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n <li>"
852 "(<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> < <i>x</i> and <i>x</i> < <i>b</i> }"
853 "</li>\\r\\n <li>[<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> \\u2264 <i>x</i> and "
854 "<i>x</i> < <i>b</i> }</li>\\r\\n <li>(<i>a</i>, <i>b</i>]: {<i>x</i> | <i>a</i> "
855 "< <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n</ul>\\r\\n\\r\\nNote that "
856 "if <i>a</i> = <i>b</i>, of the four only [<i>a</i>, <i>a</i>] would be non-empty."
857 "\\r\\n\\r\\n<strong>Task</strong>\\r\\n\\r\\n<ul>\\r\\n <li>Devise a way to "
858 "represent any set of real numbers, for the definition of \\\"any\\\" in the "
859 "implementation notes below.</li>\\r\\n <li>Provide methods for these common "
860 "set operations (<i>x</i> is a real number; <i>A</i> and <i>B</i> are sets):</li>"
861 "\\r\\n <ul>\\r\\n <li>\\r\\n <i>x</i> \\u2208 <i>A</i>: determine if <i>"
862 "x</i> is an element of <i>A</i><br>\\r\\n example: 1 is in [1, 2), while 2, "
863 "3, ... are not.\\r\\n </li>\\r\\n <li>\\r\\n <i>A</i> \\u222A <i>B</i>: "
864 "union of <i>A</i> and <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 <i>A</i> or <i>x"
865 "</i> \\u2208 <i>B</i>}<br>\\r\\n example: [0, 2) \\u222A (1, 3) = [0, 3); "
866 "[0, 1) \\u222A (2, 3] = well, [0, 1) \\u222A (2, 3]\\r\\n </li>\\r\\n <li>"
867 "\\r\\n <i>A</i> \\u2229 <i>B</i>: intersection of <i>A</i> and <i>B</i>, i.e. "
868 "{<i>x</i> | <i>x</i> \\u2208 <i>A</i> and <i>x</i> \\u2208 <i>B</i>}<br>\\r\\n "
869 "example: [0, 2) \\u2229 (1, 3) = (1, 2); [0, 1) \\u2229 (2, 3] = empty set\\r\\n "
870 "</li>\\r\\n <li>\\r\\n <i>A</i> - <i>B</i>: difference between <i>A</i> and "
871 "<i>B</i>, also written as <i>A</i> \\\\ <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 "
872 "<i>A</i> and <i>x</i> \\u2209 <i>B</i>}<br>\\r\\n example: [0, 2) \\u2212 (1, "
873 "3) = [0, 1]\\r\\n </li>\\r\\n </ul>\\r\\n</ul>\\r\\n</section>\\r\\n\"\n";
881 constexpr static std::size_t max_object_size
= std::size_t(-1);
882 constexpr static std::size_t max_array_size
= std::size_t(-1);
883 constexpr static std::size_t max_key_size
= std::size_t(-1);
884 constexpr static std::size_t max_string_size
= std::size_t(-1);
886 std::string captured
= "";
887 bool on_document_begin( error_code
& ) { return true; }
888 bool on_document_end( error_code
& ) { return true; }
889 bool on_object_begin( error_code
& ) { return true; }
890 bool on_object_end( std::size_t, error_code
& ) { return true; }
891 bool on_array_begin( error_code
& ) { return true; }
892 bool on_array_end( std::size_t, error_code
& ) { return true; }
893 bool on_key_part( string_view
, std::size_t, error_code
& ) { return true; }
894 bool on_key( string_view
, std::size_t, error_code
& ) { return true; }
895 bool on_string_part( string_view
, std::size_t, error_code
& ) { return true; }
896 bool on_string( string_view
, std::size_t, error_code
& ) { return true; }
897 bool on_number_part( string_view
, error_code
&) { return true; }
898 bool on_int64( std::int64_t, string_view
, error_code
& ) { return true; }
899 bool on_uint64( std::uint64_t, string_view
, error_code
& ) { return true; }
900 bool on_double( double, string_view
, error_code
& ) { return true; }
901 bool on_bool( bool, error_code
& ) { return true; }
902 bool on_null( error_code
& ) { return true; }
903 bool on_comment_part( string_view s
, error_code
& )
905 captured
.append(s
.data(), s
.size());
908 bool on_comment( string_view s
, error_code
& )
910 captured
.append(s
.data(), s
.size());
915 basic_parser
<handler
> p_
;
919 : p_(make_options(true, false, false))
929 auto const n
= p_
.write_some(
930 false, data
, size
, ec
);
932 ec
= error::extra_data
;
937 captured() const noexcept
939 return p_
.handler().captured
;
946 parse_options disabled
;
947 parse_options enabled
;
948 enabled
.allow_comments
= true;
950 const auto replace_and_test
=
953 static std::vector
<string_view
> comments
=
970 std::string formatted
= "";
971 std::string just_comments
= "";
972 std::size_t guess
= std::count(
973 s
.begin(), s
.end(), '@') * 12;
974 formatted
.reserve(guess
+ s
.size());
975 just_comments
.reserve(guess
);
982 comments
[((formatted
.size() + n
) % s
.size()) % comments
.size()];
983 formatted
.append(com
.data(), n
= com
.size());
984 just_comments
.append(com
.data(), com
.size());
989 bad(formatted
, disabled
);
990 good(formatted
, enabled
);
996 p
.write( formatted
.data(), formatted
.size(), ec
);
998 BOOST_TEST(p
.captured() == just_comments
);
1002 replace_and_test("@1");
1003 replace_and_test("1@");
1004 replace_and_test("@1@");
1005 replace_and_test("[@1]");
1006 replace_and_test("[1@]");
1007 replace_and_test("[1,2@]");
1008 replace_and_test("[1,@2]");
1009 replace_and_test("[1@,2]");
1010 replace_and_test("@[@1@,@2@]@");
1011 replace_and_test("{@\"a\":1}");
1012 replace_and_test("{\"a\"@:1}");
1013 replace_and_test("{\"a\":1@}");
1014 replace_and_test("{\"a\":1@,\"b\":2}");
1015 replace_and_test("{\"a\":1,@\"b\":2}");
1016 replace_and_test("@{@\"a\"@:@1@,@\"b\"@:@2@}");
1018 // no following token
1021 bad("1/x", enabled
);
1023 bad("1/*", enabled
);
1024 bad("1/**", enabled
);
1025 bad("[1 //, 2]", enabled
);
1028 bad("//\n", enabled
);
1030 bad("/**/", enabled
);
1032 // no newline at EOF
1033 good("1//", enabled
);
1039 parse_options disabled
;
1040 parse_options enabled
;
1041 enabled
.allow_trailing_commas
= true;
1043 bad("[1,]", disabled
);
1044 good("[1,]", enabled
);
1046 bad("[1,[],]", disabled
);
1047 good("[1,[],]", enabled
);
1049 bad("[1,{},]", disabled
);
1050 good("[1,{},]", enabled
);
1052 bad("[1,{\"a\":1,},]", disabled
);
1053 good("[1,{\"a\":1,},]", enabled
);
1055 bad("{\"a\":1,}", disabled
);
1056 good("{\"a\":1,}", enabled
);
1058 bad("{\"a\":[1,],}", disabled
);
1059 good("{\"a\":[1,],}", enabled
);
1061 bad("{\"a\":[],}", disabled
);
1062 good("{\"a\":[],}", enabled
);
1064 bad("{\"a\":[{}, [1,]],}", disabled
);
1065 good("{\"a\":[{}, [1,]],}", enabled
);
1067 bad("[[[[[[[],],],],],],]", disabled
);
1068 good("[[[[[[[],],],],],],]", enabled
);
1070 bad("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", disabled
);
1071 good("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", enabled
);
1078 constexpr static std::size_t max_object_size
= std::size_t(-1);
1079 constexpr static std::size_t max_array_size
= std::size_t(-1);
1080 constexpr static std::size_t max_key_size
= std::size_t(-1);
1081 constexpr static std::size_t max_string_size
= std::size_t(-1);
1083 std::string captured
= "";
1084 bool on_document_begin( error_code
& ) { return true; }
1085 bool on_document_end( error_code
& ) { return true; }
1086 bool on_object_begin( error_code
& ) { return true; }
1087 bool on_object_end( std::size_t, error_code
& ) { return true; }
1088 bool on_array_begin( error_code
& ) { return true; }
1089 bool on_array_end( std::size_t, error_code
& ) { return true; }
1090 bool on_key_part( string_view
, std::size_t, error_code
& ) { return true; }
1091 bool on_key( string_view
, std::size_t, error_code
& ) { return true; }
1092 bool on_string_part( string_view sv
, std::size_t, error_code
& )
1094 captured
.append(sv
.data(), sv
.size());
1097 bool on_string( string_view sv
, std::size_t, error_code
& )
1099 captured
.append(sv
.data(), sv
.size());
1102 bool on_number_part( string_view
, error_code
&) { return true; }
1103 bool on_int64( std::int64_t, string_view
, error_code
& ) { return true; }
1104 bool on_uint64( std::uint64_t, string_view
, error_code
& ) { return true; }
1105 bool on_double( double, string_view
, error_code
& ) { return true; }
1106 bool on_bool( bool, error_code
& ) { return true; }
1107 bool on_null( error_code
& ) { return true; }
1108 bool on_comment_part( string_view
, error_code
& ) { return true; }
1109 bool on_comment( string_view
, error_code
& ) { return true; }
1112 basic_parser
<handler
> p_
;
1116 : p_(parse_options())
1127 auto const n
= p_
.write_some(
1128 more
, data
, size
, ec
);
1129 if(! ec
&& n
< size
)
1130 ec
= error::extra_data
;
1135 captured() const noexcept
1137 return p_
.handler().captured
;
1142 testUTF8Validation()
1144 good("\"\xc2\x80----------\"");
1145 good("\"\xc2\xbf----------\"");
1146 good("\"\xdf\x80----------\"");
1147 good("\"\xdf\xbf----------\"");
1149 good("\"\xcf\x90----------\"");
1151 good("\"\xe0\xa0\x80----------\"");
1152 good("\"\xe0\xa0\xbf----------\"");
1153 good("\"\xe0\xbf\x80----------\"");
1154 good("\"\xe0\xbf\xbf----------\"");
1156 good("\"\xe0\xb0\x90----------\"");
1158 good("\"\xe1\x80\x80----------\"");
1159 good("\"\xe1\xbf\x80----------\"");
1160 good("\"\xec\x80\x80----------\"");
1161 good("\"\xec\xbf\x80----------\"");
1162 good("\"\xe1\x80\xbf----------\"");
1163 good("\"\xe1\xbf\xbf----------\"");
1164 good("\"\xec\x80\xbf----------\"");
1165 good("\"\xec\xbf\xbf----------\"");
1167 good("\"\xe6\x90\x90----------\"");
1169 good("\"\xed\x80\x80----------\"");
1170 good("\"\xed\x80\xbf----------\"");
1171 good("\"\xed\x9f\x80----------\"");
1172 good("\"\xed\x9f\xbf----------\"");
1174 good("\"\xed\x90\x90----------\"");
1176 good("\"\xee\x80\x80----------\"");
1177 good("\"\xee\xbf\x80----------\"");
1178 good("\"\xef\x80\x80----------\"");
1179 good("\"\xef\xbf\x80----------\"");
1180 good("\"\xee\x80\xbf----------\"");
1181 good("\"\xee\xbf\xbf----------\"");
1182 good("\"\xef\x80\xbf----------\"");
1183 good("\"\xef\xbf\xbf----------\"");
1185 good("\"\xee\x90\x90----------\"");
1186 good("\"\xef\x90\x90----------\"");
1188 good("\"\xf0\x90\x80\x80----------\"");
1189 good("\"\xf0\x90\xbf\x80----------\"");
1190 good("\"\xf0\x90\xbf\xbf----------\"");
1191 good("\"\xf0\x90\x80\xbf----------\"");
1192 good("\"\xf0\xbf\x80\x80----------\"");
1193 good("\"\xf0\xbf\xbf\x80----------\"");
1194 good("\"\xf0\xbf\xbf\xbf----------\"");
1195 good("\"\xf0\xbf\x80\xbf----------\"");
1197 good("\"\xf0\xA0\x90\x90----------\"");
1199 good("\"\xf4\x80\x80\x80----------\"");
1200 good("\"\xf4\x80\xbf\x80----------\"");
1201 good("\"\xf4\x80\xbf\xbf----------\"");
1202 good("\"\xf4\x80\x80\xbf----------\"");
1203 good("\"\xf4\x8f\x80\x80----------\"");
1204 good("\"\xf4\x8f\xbf\x80----------\"");
1205 good("\"\xf4\x8f\xbf\xbf----------\"");
1206 good("\"\xf4\x8f\x80\xbf----------\"");
1208 good("\"\xf4\x88\x90\x90----------\"");
1210 good("\"\xf1\x80\x80\x80----------\"");
1211 good("\"\xf1\x80\xbf\x80----------\"");
1212 good("\"\xf1\x80\xbf\xbf----------\"");
1213 good("\"\xf1\x80\x80\xbf----------\"");
1214 good("\"\xf1\xbf\x80\x80----------\"");
1215 good("\"\xf1\xbf\xbf\x80----------\"");
1216 good("\"\xf1\xbf\xbf\xbf----------\"");
1217 good("\"\xf1\xbf\x80\xbf----------\"");
1218 good("\"\xf3\x80\x80\x80----------\"");
1219 good("\"\xf3\x80\xbf\x80----------\"");
1220 good("\"\xf3\x80\xbf\xbf----------\"");
1221 good("\"\xf3\x80\x80\xbf----------\"");
1222 good("\"\xf3\xbf\x80\x80----------\"");
1223 good("\"\xf3\xbf\xbf\x80----------\"");
1224 good("\"\xf3\xbf\xbf\xbf----------\"");
1225 good("\"\xf3\xbf\x80\xbf----------\"");
1227 good("\"\xf2\x90\x90\x90----------\"");
1229 bad("\"\xc0\x80----------\"");
1230 bad("\"\xc2\xc0----------\"");
1231 bad("\"\xef\x80----------\"");
1232 bad("\"\xdf\x70----------\"");
1234 bad("\"\xff\x90----------\"");
1236 bad("\"\xe0\x9f\x80----------\"");
1237 bad("\"\xe0\xa0\xfe----------\"");
1238 bad("\"\xc0\xff\xff----------\"");
1239 bad("\"\xc0\xbf\x76----------\"");
1241 bad("\"\xe0\xde\x90----------\"");
1243 bad("\"\xe1\x80\x7f----------\"");
1244 bad("\"\xe1\x7f\x80----------\"");
1245 bad("\"\xec\xff\x80----------\"");
1246 bad("\"\xef\x7f\x80----------\"");
1247 bad("\"\xe1\x80\xff----------\"");
1248 bad("\"\xe1\xbf\x0f----------\"");
1249 bad("\"\xec\x01\xff----------\"");
1250 bad("\"\xec\xff\xff----------\"");
1252 bad("\"\xe6\x60\x90----------\"");
1254 bad("\"\xed\x7f\x80----------\"");
1255 bad("\"\xed\xa0\xbf----------\"");
1256 bad("\"\xed\xbf\x80----------\"");
1257 bad("\"\xed\x9f\x7f----------\"");
1259 bad("\"\xed\xce\xbf----------\"");
1261 bad("\"\xee\x7f\x80----------\"");
1262 bad("\"\xee\xcc\x80----------\"");
1263 bad("\"\xef\x80\xcc----------\"");
1264 bad("\"\xef\xbf\x0a----------\"");
1265 bad("\"\xee\x50\xbf----------\"");
1266 bad("\"\xee\xef\xbf----------\"");
1267 bad("\"\xef\xf0\xff----------\"");
1268 bad("\"\xef\xaa\xee----------\"");
1270 bad("\"\xc0\x90\x90----------\"");
1271 bad("\"\xc1\x90\x90----------\"");
1273 bad("\"\xff\x90\x80\x80----------\"");
1274 bad("\"\xfe\x90\xbf\x80----------\"");
1275 bad("\"\xfd\x90\xbf\xbf----------\"");
1276 bad("\"\xf0\xff\x80\xbf----------\"");
1277 bad("\"\xf0\xfe\x80\x80----------\"");
1278 bad("\"\xf0\xfd\xbf\x80----------\"");
1279 bad("\"\xf0\x90\x80\xff----------\"");
1280 bad("\"\xf0\x90\x5f\x80----------\"");
1282 bad("\"\xf4\x70\x80\x80----------\"");
1283 bad("\"\xf4\x80\x70\x80----------\"");
1284 bad("\"\xf4\x80\xbf\x70----------\"");
1285 bad("\"\xf4\xce\x80\xbf----------\"");
1286 bad("\"\xf4\x8f\xce\x80----------\"");
1287 bad("\"\xf4\x8f\xbf\xce----------\"");
1289 bad("\"\xf1\x7f\xbf\xbf----------\"");
1290 bad("\"\xf2\x80\x7f\xbf----------\"");
1291 bad("\"\xf3\x80\xbf\xce----------\"");
1293 // utf8 after escape
1294 good("\"\\u0000 \xf3\xbf\x80\xbf\xf3\xbf\x80\xbf\"");
1295 good("\"\\ud7ff\xf4\x80\xbf\xbf \"");
1296 good("\"\\ue000 \xef\xbf\x80\"");
1297 good("\"\xef\xbf\x80 \\uffff \xef\xbf\x80\"");
1298 good("\"\xc2\x80\xc2\x80\xc2\x80\xc2\x80\xc2\x80\\ud800\\udc00 \"");
1299 good("\"\\udbff\\udfff \xe1\x80\xbf \\udbff\\udfff \xe1\x80\xbf\"");
1300 good("\"\\u0000\xe1\x80\xbf \"");
1301 bad("\"\\t\\t\xf4\x70\x80\x80----------\"");
1302 bad("\"\\n\xf4\x80\x70\x80----------\"");
1303 bad("\"\\n\xf4\x80\xbf\x70-\\n\xf4\x80\xbf\x70\"");
1306 [this](string_view expected
)
1309 for (std::size_t write_size
: {2, 4, 8})
1312 for(std::size_t i
= 0; i
< expected
.size(); i
+= write_size
)
1315 write_size
= (std::min
)(write_size
, expected
.size() - i
);
1316 auto more
= (i
< expected
.size() - write_size
);
1317 auto written
= p
.write(more
,
1318 expected
.data() + i
, write_size
, ec
);
1319 BOOST_TEST(written
== write_size
);
1322 BOOST_TEST(p
.captured() ==
1323 expected
.substr(1, expected
.size() - 2));
1327 check("\"\xd1\x82\"");
1328 check("\"\xd1\x82\xd0\xb5\xd1\x81\xd1\x82\"");
1329 check("\"\xc3\x0b1""and\xc3\xba\"");
1336 string_view s
= "[[[[[]]]]]";
1341 p
.write(s
.data(), s
.size(), ec
);
1342 BOOST_TEST(ec
== error::too_deep
);
1345 string_view s
= "[[[[]]], [[[[]]]]]";
1350 p
.write(s
.data(), s
.size(), ec
);
1351 BOOST_TEST(ec
== error::too_deep
);
1355 "{\"a\":{\"b\":{\"c\":{}}},\"b\":{\"c\":{\"d\":{\"e\":{}}}}}";
1360 p
.write(s
.data(), s
.size(), ec
);
1361 BOOST_TEST(ec
== error::too_deep
);
1365 "{\"a\":{\"b\":{\"c\":{\"d\":{}}}}}";
1370 p
.write(s
.data(), s
.size(), ec
);
1371 BOOST_TEST(ec
== error::too_deep
);
1375 class literal_parser
1379 constexpr static std::size_t max_object_size
= std::size_t(-1);
1380 constexpr static std::size_t max_array_size
= std::size_t(-1);
1381 constexpr static std::size_t max_key_size
= std::size_t(-1);
1382 constexpr static std::size_t max_string_size
= std::size_t(-1);
1384 std::string captured
= "";
1385 bool on_document_begin( error_code
& ) { return true; }
1386 bool on_document_end( error_code
& ) { return true; }
1387 bool on_object_begin( error_code
& ) { return true; }
1388 bool on_object_end( std::size_t, error_code
& ) { return true; }
1389 bool on_array_begin( error_code
& ) { return true; }
1390 bool on_array_end( std::size_t, error_code
& ) { return true; }
1391 bool on_key_part( string_view
, std::size_t, error_code
& ) { return true; }
1392 bool on_key( string_view
, std::size_t, error_code
& ) { return true; }
1393 bool on_string_part( string_view
, std::size_t, error_code
& ) { return true; }
1394 bool on_string( string_view
, std::size_t, error_code
& ) { return true; }
1395 bool on_number_part( string_view sv
, error_code
&)
1397 captured
.append(sv
.data(), sv
.size());
1400 bool on_int64( std::int64_t, string_view sv
, error_code
& )
1402 captured
.append(sv
.data(), sv
.size());
1406 bool on_uint64( std::uint64_t, string_view sv
, error_code
& )
1408 captured
.append(sv
.data(), sv
.size());
1412 bool on_double( double, string_view sv
, error_code
& )
1414 captured
.append(sv
.data(), sv
.size());
1418 bool on_bool( bool, error_code
& ) { return true; }
1419 bool on_null( error_code
& ) { return true; }
1420 bool on_comment_part( string_view
, error_code
& ) { return true; }
1421 bool on_comment( string_view
, error_code
& ) { return true; }
1424 basic_parser
<handler
> p_
;
1428 : p_(make_options(true, false, false))
1439 auto const n
= p_
.write_some(
1440 more
, data
, size
, ec
);
1441 if(! ec
&& n
< size
)
1442 ec
= error::extra_data
;
1449 return p_
.handler().captured
;
1457 [](string_view expected
)
1459 string_view sv
= expected
;
1460 sv
.remove_suffix(1);
1461 for(std::size_t i
= 0;
1471 if(BOOST_TEST(! ec
))
1478 BOOST_TEST(p
.captured() == expected
);
1488 check("9223372036854775808u");
1497 check("-100000000000000000000000d");
1498 check("100000000000000000000000d");
1499 check("10000000000.10000000000000d");
1500 check("-10000000000.10000000000000d");
1501 check("1000000000000000.0e1000000d");
1510 p
.write("*", 1, ec
);
1513 p
.write("[]", 2, ec2
);
1514 BOOST_TEST(ec2
== ec
);
1516 p
.write("[]", 2, ec2
);
1520 // exceptions do not cause UB
1526 p
.write(false, "null", 4, ec
);
1529 catch(std::exception
const&)
1532 p
.write(false, "null", 4, ec
);
1533 BOOST_TEST(ec
== error::exception
);
1553 testAllowTrailing();
1555 testUTF8Validation();
1557 testNumberLiteral();
1562 TEST_SUITE(basic_parser_test
, "boost.json.basic_parser");