]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/nlohmann-json/test/src/unit-regression1.cpp
3 __| | __| | | | JSON for Modern C++ (test suite)
4 | | |__ | | | | | | version 3.10.5
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
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:
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
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
30 #include "doctest_compatibility.h"
32 // for some reason including this after the json header leads to linker errors with VS 2017...
35 #define JSON_TESTS_PRIVATE
36 #include <nlohmann/json.hpp>
43 #include <test_data.hpp>
45 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
46 #define JSON_HAS_CPP_17
49 #ifdef JSON_HAS_CPP_17
53 #include "fifo_map.hpp"
55 /////////////////////////////////////////////////////////////////////
57 /////////////////////////////////////////////////////////////////////
59 template < class K
, class V
, class dummy_compare
, class A
>
60 using my_workaround_fifo_map
= nlohmann :: fifo_map
< K
, V
, nlohmann :: fifo_map_compare
< K
>, A
>;
61 using my_json
= nlohmann :: basic_json
< my_workaround_fifo_map
>;
63 /////////////////////////////////////////////////////////////////////
65 /////////////////////////////////////////////////////////////////////
74 template < typename
, typename SFINAE
= void >
75 struct foo_serializer
;
78 struct foo_serializer
< T
, typename
std :: enable_if
< std :: is_same
< foo
, T
>:: value
>:: type
>
80 template < typename BasicJsonType
>
81 static void to_json ( BasicJsonType
& j
, const T
& value
)
83 j
= BasicJsonType
{{ "x" , value
. x
}};
85 template < typename BasicJsonType
>
86 static void from_json ( const BasicJsonType
& j
, T
& value
) // !!!
88 nlohmann :: from_json ( j
. at ( "x" ), value
. x
);
93 struct foo_serializer
< T
, typename
std :: enable_if
< ! std :: is_same
< foo
, T
>:: value
>:: type
>
95 template < typename BasicJsonType
>
96 static void to_json ( BasicJsonType
& j
, const T
& value
) noexcept
// NOLINT(bugprone-exception-escape)
98 :: nlohmann :: to_json ( j
, value
);
100 template < typename BasicJsonType
>
101 static void from_json ( const BasicJsonType
& j
, T
& value
) //!!!
103 :: nlohmann :: from_json ( j
, value
);
108 using foo_json
= nlohmann :: basic_json
< std :: map
, std :: vector
, std :: string
, bool , std :: int64_t ,
109 std :: uint64_t , double , std :: allocator
, ns :: foo_serializer
, std :: vector
< std :: uint8_t >>;
111 /////////////////////////////////////////////////////////////////////
113 /////////////////////////////////////////////////////////////////////
117 struct nocopy
// NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
120 nocopy ( const nocopy
&) = delete ;
121 nocopy ( nocopy
&&) = delete ;
122 nocopy
& operator =( const nocopy
&) = delete ;
123 nocopy
& operator =( nocopy
&&) = delete ;
127 friend void to_json ( json
& j
, const nocopy
& n
)
129 j
= {{ "val" , n
. val
}};
134 TEST_CASE ( "regression tests 1" )
136 SECTION ( "issue #60 - Double quotation mark is not parsed correctly" )
138 SECTION ( "escape_doublequote" )
140 const auto * s
= R
"([" \" foo
\" "])" ;
141 json j
= json :: parse ( s
);
142 auto expected
= R
"([" \" foo
\" "])" _json
;
143 CHECK ( j
== expected
);
147 SECTION ( "issue #70 - Handle infinity and NaN cases" )
149 // previously, NAN/INFINITY created a null value; now, the values are
150 // properly stored, but are dumped as "null"
153 CHECK ( json ( NAN
). dump () == "null" );
154 CHECK ( json ( json :: number_float_t ( NAN
)). dump () == "null" );
159 CHECK ( json ( INFINITY
). dump () == "null" );
160 CHECK ( json ( json :: number_float_t ( INFINITY
)). dump () == "null" );
163 // With 3.0.0, the semantics of this changed: NAN and infinity are
164 // stored properly inside the JSON value (no exception or conversion
165 // to null), but are serialized as null.
169 CHECK ( j1
. is_number_float ());
170 json :: number_float_t f1
{ j1
};
171 CHECK ( std :: isnan ( f1
));
173 json j2
= static_cast < json :: number_float_t
>( NAN
);
174 CHECK ( j2
. is_number_float ());
175 json :: number_float_t f2
{ j2
};
176 CHECK ( std :: isnan ( f2
));
182 CHECK ( j1
. is_number_float ());
183 json :: number_float_t f1
{ j1
};
184 CHECK (! std :: isfinite ( f1
));
186 json j2
= static_cast < json :: number_float_t
>( INFINITY
);
187 CHECK ( j2
. is_number_float ());
188 json :: number_float_t f2
{ j2
};
189 CHECK (! std :: isfinite ( f2
));
193 SECTION ( "pull request #71 - handle enum type" )
195 enum { t
= 0 , u
= 102 };
196 json j
= json :: array ();
199 // maybe this is not the place to test this?
202 auto anon_enum_value
= j2
. get
< decltype ( u
)>();
203 CHECK ( u
== anon_enum_value
);
205 // check if the actual value was stored
208 static_assert ( std :: is_same
< decltype ( anon_enum_value
), decltype ( u
)>:: value
, "types must be the same" );
210 j
. push_back ( json :: object (
216 SECTION ( "issue #76 - dump() / parse() not idempotent" )
218 // create JSON object
220 fields
[ "one" ] = std :: string ( "one" );
221 fields
[ "two" ] = std :: string ( "two three" );
222 fields
[ "three" ] = std :: string ( "three \" four \" " );
224 // create another JSON object by deserializing the serialization
225 std :: string payload
= fields
. dump ();
226 json parsed_fields
= json :: parse ( payload
);
228 // check individual fields to match both objects
229 CHECK ( parsed_fields
[ "one" ] == fields
[ "one" ]);
230 CHECK ( parsed_fields
[ "two" ] == fields
[ "two" ]);
231 CHECK ( parsed_fields
[ "three" ] == fields
[ "three" ]);
233 // check individual fields to match original input
234 CHECK ( parsed_fields
[ "one" ] == std :: string ( "one" ));
235 CHECK ( parsed_fields
[ "two" ] == std :: string ( "two three" ));
236 CHECK ( parsed_fields
[ "three" ] == std :: string ( "three \" four \" " ));
238 // check equality of the objects
239 CHECK ( parsed_fields
== fields
);
241 // check equality of the serialized objects
242 CHECK ( fields
. dump () == parsed_fields
. dump ());
244 // check everything in one line
245 CHECK ( fields
== json :: parse ( fields
. dump ()));
248 SECTION ( "issue #82 - lexer::get_number return NAN" )
250 const auto * const content
= R
"(
257 std :: stringstream ss
;
262 auto test
= j
[ "Test" ]. get
< std :: string
>();
263 CHECK ( test
== "Test1" );
264 int number
{ j
[ "Number" ]};
265 CHECK ( number
== 100 );
267 CHECK ( static_cast < double >( foo
) == Approx ( 42.42 ));
270 SECTION ( "issue #89 - nonstandard integer type" )
272 // create JSON class with nonstandard integer number type
274 nlohmann :: basic_json
< std :: map
, std :: vector
, std :: string
, bool , int32_t , uint32_t , float >;
277 CHECK ( j
[ "int_1" ] == 1 );
279 // tests for correct handling of non-standard integers that overflow the type selected by the user
281 // unsigned integer object creation - expected to wrap and still be stored as an integer
282 j
= 4294967296U ; // 2^32
283 CHECK ( static_cast < int >( j
. type ()) == static_cast < int >( custom_json :: value_t :: number_unsigned
));
284 CHECK ( j
. get
< uint32_t >() == 0 ); // Wrap
286 // unsigned integer parsing - expected to overflow and be stored as a float
287 j
= custom_json :: parse ( "4294967296" ); // 2^32
288 CHECK ( static_cast < int >( j
. type ()) == static_cast < int >( custom_json :: value_t :: number_float
));
289 CHECK ( j
. get
< float >() == 4294967296.0 f
);
291 // integer object creation - expected to wrap and still be stored as an integer
292 j
= - 2147483649LL ; // -2^31-1
293 CHECK ( static_cast < int >( j
. type ()) == static_cast < int >( custom_json :: value_t :: number_integer
));
294 CHECK ( j
. get
< int32_t >() == 2147483647 ); // Wrap
296 // integer parsing - expected to overflow and be stored as a float with rounding
297 j
= custom_json :: parse ( "-2147483649" ); // -2^31
298 CHECK ( static_cast < int >( j
. type ()) == static_cast < int >( custom_json :: value_t :: number_float
));
299 CHECK ( j
. get
< float >() == - 2147483650.0 f
);
302 SECTION ( "issue #93 reverse_iterator operator inheritance problem" )
306 json :: reverse_iterator rit
= a
. rbegin ();
308 CHECK (* rit
== json ( 2 ));
309 CHECK ( rit
. value () == json ( 2 ));
313 json :: reverse_iterator rit
= ++ a
. rbegin ();
314 CHECK (* rit
== json ( 2 ));
315 CHECK ( rit
. value () == json ( 2 ));
319 json :: reverse_iterator rit
= a
. rbegin ();
322 std :: transform ( rit
, a
. rend (), b
. rbegin (), []( json el
)
326 CHECK ( b
== json ({ 0 , 1 , 2 }));
331 std :: transform (++ a
. rbegin (), a
. rend (), b
. rbegin (), []( json el
)
335 CHECK ( b
== json ({ 0 , 1 , 2 }));
339 SECTION ( "issue #100 - failed to iterator json object with reverse_iterator" )
348 std :: stringstream ss
;
350 for ( auto it
= config
. begin (); it
!= config
. end (); ++ it
)
352 ss
<< it
. key () << ": " << it
. value () << ' \n ' ;
355 for ( auto it
= config
. rbegin (); it
!= config
. rend (); ++ it
)
357 ss
<< it
. key () << ": " << it
. value () << ' \n ' ;
360 CHECK ( ss
. str () == "111: 111 \n 112: 112 \n 113: 113 \n 113: 113 \n 112: 112 \n 111: 111 \n " );
363 SECTION ( "issue #101 - binary string causes numbers to be dumped as hex" )
366 std :: string bytes
{ " \x00 " "asdf \n " , 6 };
369 j
[ "binary string" ] = bytes
;
370 // make sure the number is really printed as decimal "10" and not as
372 CHECK ( j
. dump () == "{ \" binary string \" : \"\\ u0000asdf \\ n \" , \" int64 \" :10}" );
375 SECTION ( "issue #111 - subsequent unicode chars" )
377 std :: string bytes
{ 0x7 , 0x7 };
380 CHECK ( j
[ "string" ] == " \u0007\u0007 " );
383 #if JSON_USE_IMPLICIT_CONVERSIONS
384 SECTION ( "issue #144 - implicit assignment to std::string fails" )
386 json o
= {{ "name" , "value" }};
388 std :: string s1
= o
[ "name" ];
389 CHECK ( s1
== "value" );
394 CHECK ( s2
== "value" );
398 CHECK_THROWS_AS ( s2
= o
[ "int" ], json :: type_error
);
400 CHECK_THROWS_WITH ( s2
= o
[ "int" ], "[json.exception.type_error.302] (/int) type must be string, but is number" );
402 CHECK_THROWS_WITH ( s2
= o
[ "int" ], "[json.exception.type_error.302] type must be string, but is number" );
407 SECTION ( "issue #146 - character following a surrogate pair is skipped" )
409 CHECK ( json :: parse ( " \"\\ ud80c \\ udc60abc \" " ). get
< json :: string_t
>() == " \xf0\x93\x81\xa0\x61\x62\x63 " );
412 SECTION ( "issue #171 - Cannot index by key of type static constexpr const char*" )
416 // Non-const access with key as "char []"
417 char array_key
[] = "Key1" ; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
418 CHECK_NOTHROW ( j
[ array_key
] = 1 );
419 CHECK ( j
[ array_key
] == json ( 1 ));
421 // Non-const access with key as "const char[]"
422 const char const_array_key
[] = "Key2" ; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
423 CHECK_NOTHROW ( j
[ const_array_key
] = 2 );
424 CHECK ( j
[ const_array_key
] == json ( 2 ));
426 // Non-const access with key as "char *"
427 char _ptr_key
[] = "Key3" ; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
428 char * ptr_key
= & _ptr_key
[ 0 ]; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
429 CHECK_NOTHROW ( j
[ ptr_key
] = 3 );
430 CHECK ( j
[ ptr_key
] == json ( 3 ));
432 // Non-const access with key as "const char *"
433 const char * const_ptr_key
= "Key4" ;
434 CHECK_NOTHROW ( j
[ const_ptr_key
] = 4 );
435 CHECK ( j
[ const_ptr_key
] == json ( 4 ));
437 // Non-const access with key as "static constexpr const char *"
438 static constexpr const char * constexpr_ptr_key
= "Key5" ;
439 CHECK_NOTHROW ( j
[ constexpr_ptr_key
] = 5 );
440 CHECK ( j
[ constexpr_ptr_key
] == json ( 5 ));
442 const json j_const
= j
;
444 // Const access with key as "char []"
445 CHECK ( j_const
[ array_key
] == json ( 1 ));
447 // Const access with key as "const char[]"
448 CHECK ( j_const
[ const_array_key
] == json ( 2 ));
450 // Const access with key as "char *"
451 CHECK ( j_const
[ ptr_key
] == json ( 3 ));
453 // Const access with key as "const char *"
454 CHECK ( j_const
[ const_ptr_key
] == json ( 4 ));
456 // Const access with key as "static constexpr const char *"
457 CHECK ( j_const
[ constexpr_ptr_key
] == json ( 5 ));
460 SECTION ( "issue #186 miloyip/nativejson-benchmark: floating-point parsing" )
464 j
= json :: parse ( "-0.0" );
465 CHECK ( j
. get
< double >() == - 0.0 );
467 j
= json :: parse ( "2.22507385850720113605740979670913197593481954635164564e-308" );
468 CHECK ( j
. get
< double >() == 2.2250738585072009e-308 );
470 j
= json :: parse ( "0.999999999999999944488848768742172978818416595458984374" );
471 CHECK ( j
. get
< double >() == 0.99999999999999989 );
473 j
= json :: parse ( "1.00000000000000011102230246251565404236316680908203126" );
474 CHECK ( j
. get
< double >() == 1.00000000000000022 );
476 j
= json :: parse ( "7205759403792793199999e-5" );
477 CHECK ( j
. get
< double >() == 72057594037927928.0 );
479 j
= json :: parse ( "922337203685477529599999e-5" );
480 CHECK ( j
. get
< double >() == 9223372036854774784.0 );
482 j
= json :: parse ( "1014120480182583464902367222169599999e-5" );
483 CHECK ( j
. get
< double >() == 10141204801825834086073718800384.0 );
485 j
= json :: parse ( "5708990770823839207320493820740630171355185151999e-3" );
486 CHECK ( j
. get
< double >() == 5708990770823838890407843763683279797179383808.0 );
488 // create JSON class with nonstandard float number type
491 nlohmann :: basic_json
< std :: map
, std :: vector
, std :: string
, bool , int32_t , uint32_t , float > j_float
=
493 CHECK ( j_float
. get
< float >() == 1.23 e25f
);
496 nlohmann :: basic_json
< std :: map
, std :: vector
, std :: string
, bool , int64_t , uint64_t , double > j_double
=
498 CHECK ( j_double
. get
< double >() == 1.23 e35
);
501 nlohmann :: basic_json
< std :: map
, std :: vector
, std :: string
, bool , int64_t , uint64_t , long double >
502 j_long_double
= 1.23 e45L
;
503 CHECK ( j_long_double
. get
< long double >() == 1.23 e45L
);
506 SECTION ( "issue #228 - double values are serialized with commas as decimal points" )
509 json j1b
= json :: parse ( "2312.42" );
513 //json j2b = json::parse("2342e-2");
516 json j3b
= json :: parse ( "10E3" );
517 json j3c
= json :: parse ( "10e3" );
519 // class to create a locale that would use a comma for decimals
520 class CommaDecimalSeparator
: public std :: numpunct
< char >
523 char do_decimal_point () const override
528 char do_thousands_sep () const override
533 std :: string
do_grouping () const override
539 // change locale to mess with decimal points
540 auto orig_locale
= std :: locale :: global ( std :: locale ( std :: locale (), new CommaDecimalSeparator
));
542 CHECK ( j1a
. dump () == "2312.42" );
543 CHECK ( j1b
. dump () == "2312.42" );
545 // check if locale is properly reset
546 std :: stringstream ss
;
547 ss
. imbue ( std :: locale ( std :: locale (), new CommaDecimalSeparator
));
549 CHECK ( ss
. str () == "4.712,11" );
551 CHECK ( ss
. str () == "4.712,112312.42" );
553 CHECK ( ss
. str () == "4.712,112312.4247,11" );
555 CHECK ( j2a
. dump () == "23.42" );
557 //CHECK(j2b.dump() == "23.42");
559 CHECK ( j3a
. dump () == "10000.0" );
560 CHECK ( j3b
. dump () == "10000.0" );
561 CHECK ( j3c
. dump () == "10000.0" );
562 //CHECK(j3b.dump() == "1E04"); // roundtrip error
563 //CHECK(j3c.dump() == "1e04"); // roundtrip error
565 std :: locale :: global ( orig_locale
);
568 SECTION ( "issue #378 - locale-independent num-to-str" )
570 static_cast < void >( setlocale ( LC_NUMERIC
, "de_DE.UTF-8" ));
572 // verify that dumped correctly with '.' and no grouping
573 const json j1
= 12345.67 ;
574 CHECK ( json ( 12345.67 ). dump () == "12345.67" );
575 static_cast < void >( setlocale ( LC_NUMERIC
, "C" ));
578 SECTION ( "issue #379 - locale-independent str-to-num" )
580 static_cast < void >( setlocale ( LC_NUMERIC
, "de_DE.UTF-8" ));
582 // verify that parsed correctly despite using strtod internally
583 CHECK ( json :: parse ( "3.14" ). get
< double >() == 3.14 );
585 // check a different code path
586 CHECK ( json :: parse ( "1.000000000000000000000000000000000000000000000000000000000000000000000000" ). get
< double >() == 1.0 );
589 SECTION ( "issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator" )
591 json source
= { "a" , "b" , "c" };
592 json expected
= { "a" , "b" };
595 std :: copy_n ( std :: make_move_iterator ( source
. begin ()), 2 , std :: back_inserter ( dest
));
597 CHECK ( dest
== expected
);
600 SECTION ( "issue #235 - ambiguous overload for 'push_back' and 'operator+='" )
602 json data
= {{ "key" , "value" }};
603 data
. push_back ({ "key2" , "value2" });
604 data
+= { "key3" , "value3" };
606 CHECK ( data
== json ({{ "key" , "value" }, { "key2" , "value2" }, { "key3" , "value3" }}));
609 SECTION ( "issue #269 - diff generates incorrect patch when removing multiple array elements" )
611 json doc
= R
"( { " arr1
": [1, 2, 3, 4] } )" _json
;
612 json expected
= R
"( { " arr1
": [1, 2] } )" _json
;
615 CHECK ( doc
. patch ( json :: diff ( doc
, expected
)) == expected
);
618 SECTION ( "issue #283 - value() does not work with _json_pointer types" )
622 { "object" , {{ "key1" , 1 }, { "key2" , 2 }}},
625 int at_integer
{ j
. at ( "/object/key2" _json_pointer
)};
626 int val_integer
= j
. value ( "/object/key2" _json_pointer
, 0 );
628 CHECK ( at_integer
== val_integer
);
631 SECTION ( "issue #304 - Unused variable warning" )
633 // code triggered a "warning: unused variable" warning and is left
634 // here to avoid the warning in the future
636 json patch
= json :: array ();
637 object
= object
. patch ( patch
);
640 SECTION ( "issue #306 - Parsing fails without space at end of file" )
642 for ( const auto * filename
:
644 TEST_DATA_DIRECTORY
"/regression/broken_file.json" ,
645 TEST_DATA_DIRECTORY
"/regression/working_file.json"
650 std :: ifstream
f ( filename
);
651 CHECK_NOTHROW ( f
>> j
);
655 SECTION ( "issue #310 - make json_benchmarks no longer working in 2.0.4" )
657 for ( const auto * filename
:
659 TEST_DATA_DIRECTORY
"/regression/floats.json" ,
660 TEST_DATA_DIRECTORY
"/regression/signed_ints.json" ,
661 TEST_DATA_DIRECTORY
"/regression/unsigned_ints.json" ,
662 TEST_DATA_DIRECTORY
"/regression/small_signed_ints.json"
667 std :: ifstream
f ( filename
);
668 CHECK_NOTHROW ( f
>> j
);
672 SECTION ( "issue #323 - add nested object capabilities to pointers" )
675 j
[ "/this/that/2" _json_pointer
] = 27 ;
676 CHECK ( j
== json ({{ "this" , {{ "that" , { nullptr , nullptr , 27 }}}}}));
679 SECTION ( "issue #329 - serialized value not always can be parsed" )
682 CHECK_THROWS_AS ( _
= json :: parse ( "22e2222" ), json :: out_of_range
&);
683 CHECK_THROWS_WITH ( _
= json :: parse ( "22e2222" ),
684 "[json.exception.out_of_range.406] number overflow parsing '22e2222'" );
687 SECTION ( "issue #360 - Loss of precision when serializing <double>" )
689 auto check_roundtrip
= []( double number
)
694 CHECK ( j
. is_number_float ());
696 std :: stringstream ss
;
699 CHECK_NOTHROW ( ss
>> j
);
700 CHECK ( j
. is_number_float ());
701 CHECK ( j
. get
< json :: number_float_t
>() == number
);
704 check_roundtrip ( 100000000000.1236 );
705 check_roundtrip (( std :: numeric_limits
< json :: number_float_t
>:: max
)());
707 // Some more numbers which fail to roundtrip when serialized with digits10 significand digits (instead of max_digits10)
708 check_roundtrip ( 1.541888611948064e-17 );
709 check_roundtrip ( 5.418771028591015e-16 );
710 check_roundtrip ( 9.398685592608595e-15 );
711 check_roundtrip ( 8.826843952762347e-14 );
712 check_roundtrip ( 8.143291313475335e-13 );
713 check_roundtrip ( 4.851328172762508e-12 );
714 check_roundtrip ( 6.677850998084358e-11 );
715 check_roundtrip ( 3.995398518174525e-10 );
716 check_roundtrip ( 1.960452605645124e-9 );
717 check_roundtrip ( 3.551812586302883e-8 );
718 check_roundtrip ( 2.947988411689261e-7 );
719 check_roundtrip ( 8.210166748056192e-6 );
720 check_roundtrip ( 6.104889704266753e-5 );
721 check_roundtrip ( 0.0008629954631330876 );
722 check_roundtrip ( 0.004936993881051611 );
723 check_roundtrip ( 0.08309725102608073 );
724 check_roundtrip ( 0.5210494268499783 );
725 check_roundtrip ( 6.382927930939767 );
726 check_roundtrip ( 59.94947245358671 );
727 check_roundtrip ( 361.0838651266122 );
728 check_roundtrip ( 4678.354596181877 );
729 check_roundtrip ( 61412.17658956043 );
730 check_roundtrip ( 725696.0799057782 );
731 check_roundtrip ( 2811732.583399828 );
732 check_roundtrip ( 30178351.07533605 );
733 check_roundtrip ( 689684880.3235844 );
734 check_roundtrip ( 5714887673.555147 );
735 check_roundtrip ( 84652038821.18808 );
736 check_roundtrip ( 156510583431.7721 );
737 check_roundtrip ( 5938450569021.732 );
738 check_roundtrip ( 83623297654460.33 );
739 check_roundtrip ( 701466573254773.6 );
740 check_roundtrip ( 1369013370304513 );
741 check_roundtrip ( 96963648023094720 ); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
742 check_roundtrip ( 3.478237409280108e+17 );
745 SECTION ( "issue #366 - json::parse on failed stream gets stuck" )
747 std :: ifstream
f ( "file_not_found.json" );
749 CHECK_THROWS_AS ( _
= json :: parse ( f
), json :: parse_error
&);
750 CHECK_THROWS_WITH ( _
= json :: parse ( f
), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
753 SECTION ( "issue #367 - calling stream at EOF" )
755 std :: stringstream ss
;
758 CHECK_NOTHROW ( ss
>> j
);
760 // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
761 // ss is not at EOF; this yielded an error before the fix
762 // (threw basic_string::append). No, it should just throw
763 // a parse error because of the EOF.
764 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
765 CHECK_THROWS_WITH ( ss
>> j
,
766 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
769 SECTION ( "issue #367 - behavior of operator>> should more closely resemble that of built-in overloads" )
773 std :: stringstream ss
;
775 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
776 CHECK_THROWS_WITH ( ss
>> j
,
777 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
780 SECTION ( "(whitespace)" )
782 std :: stringstream ss
;
785 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
786 CHECK_THROWS_WITH ( ss
>> j
,
787 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
792 std :: stringstream ss
;
795 CHECK_NOTHROW ( ss
>> j
);
798 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
799 CHECK_THROWS_WITH ( ss
>> j
,
800 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
803 SECTION ( "one value + whitespace" )
805 std :: stringstream ss
;
808 CHECK_NOTHROW ( ss
>> j
);
811 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
812 CHECK_THROWS_WITH ( ss
>> j
,
813 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
816 SECTION ( "whitespace + one value" )
818 std :: stringstream ss
;
821 CHECK_NOTHROW ( ss
>> j
);
824 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
825 CHECK_THROWS_WITH ( ss
>> j
,
826 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
829 SECTION ( "three values" )
831 std :: stringstream ss
;
832 ss
<< " 111 \n 222 \n \n 333" ;
834 CHECK_NOTHROW ( ss
>> j
);
836 CHECK_NOTHROW ( ss
>> j
);
838 CHECK_NOTHROW ( ss
>> j
);
841 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
842 CHECK_THROWS_WITH ( ss
>> j
,
843 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
846 SECTION ( "literals without whitespace" )
848 std :: stringstream ss
;
849 ss
<< "truefalsenull \"\" " ;
851 CHECK_NOTHROW ( ss
>> j
);
853 CHECK_NOTHROW ( ss
>> j
);
855 CHECK_NOTHROW ( ss
>> j
);
857 CHECK_NOTHROW ( ss
>> j
);
860 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
861 CHECK_THROWS_WITH ( ss
>> j
,
862 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
865 SECTION ( "example from #529" )
867 std :: stringstream ss
;
868 ss
<< "{ \n \" one \" : 1, \n \" two \" : 2 \n } \n { \n \" three \" : 3 \n }" ;
870 CHECK_NOTHROW ( ss
>> j
);
871 CHECK ( j
== json ({{ "one" , 1 }, { "two" , 2 }}));
872 CHECK_NOTHROW ( ss
>> j
);
873 CHECK ( j
== json ({{ "three" , 3 }}));
875 CHECK_THROWS_AS ( ss
>> j
, json :: parse_error
&);
876 CHECK_THROWS_WITH ( ss
>> j
,
877 "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" );
880 SECTION ( "second example from #529" )
882 std :: string str
= "{ \n\" one \" : 1, \n\" two \" : 2 \n } \n { \n\" three \" : 3 \n }" ;
885 std :: ofstream
file ( "test.json" );
889 std :: ifstream
stream ( "test.json" , std :: ifstream :: in
);
893 while ( stream
. peek () != EOF
)
896 CHECK_NOTHROW ( stream
>> val
);
902 CHECK ( val
== json ({{ "one" , 1 }, { "two" , 2 }}));
907 CHECK ( val
== json ({{ "three" , 3 }}));
913 static_cast < void >( std :: remove ( "test.json" ));
917 SECTION ( "issue #389 - Integer-overflow (OSS-Fuzz issue 267)" )
919 // original test case
920 json j1
= json :: parse ( "-9223372036854775808" );
921 CHECK ( j1
. is_number_integer ());
922 CHECK ( j1
. get
< json :: number_integer_t
>() == INT64_MIN
);
924 // edge case (+1; still an integer)
925 json j2
= json :: parse ( "-9223372036854775807" );
926 CHECK ( j2
. is_number_integer ());
927 CHECK ( j2
. get
< json :: number_integer_t
>() == INT64_MIN
+ 1 );
929 // edge case (-1; overflow -> floats)
930 json j3
= json :: parse ( "-9223372036854775809" );
931 CHECK ( j3
. is_number_float ());
934 SECTION ( "issue #380 - bug in overflow detection when parsing integers" )
936 json j
= json :: parse ( "166020696663385964490" );
937 CHECK ( j
. is_number_float ());
938 CHECK ( j
. get
< json :: number_float_t
>() == 166020696663385964490.0 );
941 SECTION ( "issue #405 - Heap-buffer-overflow (OSS-Fuzz issue 342)" )
943 // original test case
944 std :: vector
< uint8_t > vec
{ 0x65 , 0xf5 , 0x0a , 0x48 , 0x21 };
946 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec
), json :: parse_error
&);
947 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec
),
948 "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input" );
951 SECTION ( "issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)" )
955 // original test case: incomplete float64
956 std :: vector
< uint8_t > vec1
{ 0xcb , 0x8f , 0x0a };
957 CHECK_THROWS_AS ( _
= json :: from_msgpack ( vec1
), json :: parse_error
&);
958 CHECK_THROWS_WITH ( _
= json :: from_msgpack ( vec1
),
959 "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input" );
961 // related test case: incomplete float32
962 std :: vector
< uint8_t > vec2
{ 0xca , 0x8f , 0x0a };
963 CHECK_THROWS_AS ( _
= json :: from_msgpack ( vec2
), json :: parse_error
&);
964 CHECK_THROWS_WITH ( _
= json :: from_msgpack ( vec2
),
965 "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input" );
967 // related test case: incomplete Half-Precision Float (CBOR)
968 std :: vector
< uint8_t > vec3
{ 0xf9 , 0x8f };
969 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec3
), json :: parse_error
&);
970 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec3
),
971 "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input" );
973 // related test case: incomplete Single-Precision Float (CBOR)
974 std :: vector
< uint8_t > vec4
{ 0xfa , 0x8f , 0x0a };
975 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec4
), json :: parse_error
&);
976 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec4
),
977 "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input" );
979 // related test case: incomplete Double-Precision Float (CBOR)
980 std :: vector
< uint8_t > vec5
{ 0xfb , 0x8f , 0x0a };
981 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec5
), json :: parse_error
&);
982 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec5
),
983 "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input" );
986 SECTION ( "issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)" )
990 // original test case
991 std :: vector
< uint8_t > vec1
{ 0x87 };
992 CHECK_THROWS_AS ( _
= json :: from_msgpack ( vec1
), json :: parse_error
&);
993 CHECK_THROWS_WITH ( _
= json :: from_msgpack ( vec1
),
994 "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input" );
996 // more test cases for MessagePack
999 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , 0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f , // fixmap
1000 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , 0x98 , 0x99 , 0x9a , 0x9b , 0x9c , 0x9d , 0x9e , 0x9f , // fixarray
1001 0xa1 , 0xa2 , 0xa3 , 0xa4 , 0xa5 , 0xa6 , 0xa7 , 0xa8 , 0xa9 , 0xaa , 0xab , 0xac , 0xad , 0xae , 0xaf , // fixstr
1002 0xb0 , 0xb1 , 0xb2 , 0xb3 , 0xb4 , 0xb5 , 0xb6 , 0xb7 , 0xb8 , 0xb9 , 0xba , 0xbb , 0xbc , 0xbd , 0xbe , 0xbf
1005 std :: vector
< uint8_t > vec ( 1 , static_cast < uint8_t >( b
));
1006 CHECK_THROWS_AS ( _
= json :: from_msgpack ( vec
), json :: parse_error
&);
1009 // more test cases for CBOR
1012 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 , 0x68 , 0x69 , 0x6a , 0x6b , 0x6c , 0x6d , 0x6e , 0x6f ,
1013 0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 , // UTF-8 string
1014 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , 0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f ,
1015 0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , // array
1016 0xa1 , 0xa2 , 0xa3 , 0xa4 , 0xa5 , 0xa6 , 0xa7 , 0xa8 , 0xa9 , 0xaa , 0xab , 0xac , 0xad , 0xae , 0xaf ,
1017 0xb0 , 0xb1 , 0xb2 , 0xb3 , 0xb4 , 0xb5 , 0xb6 , 0xb7 // map
1020 std :: vector
< uint8_t > vec ( 1 , static_cast < uint8_t >( b
));
1021 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec
), json :: parse_error
&);
1024 // special case: empty input
1025 std :: vector
< uint8_t > vec2
;
1026 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec2
), json :: parse_error
&);
1027 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec2
),
1028 "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input" );
1029 CHECK_THROWS_AS ( _
= json :: from_msgpack ( vec2
), json :: parse_error
&);
1030 CHECK_THROWS_WITH ( _
= json :: from_msgpack ( vec2
),
1031 "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input" );
1034 SECTION ( "issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)" )
1038 // original test case: empty UTF-8 string (indefinite length)
1039 std :: vector
< uint8_t > vec1
{ 0x7f };
1040 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec1
), json :: parse_error
&);
1041 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec1
),
1042 "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input" );
1044 // related test case: empty array (indefinite length)
1045 std :: vector
< uint8_t > vec2
{ 0x9f };
1046 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec2
), json :: parse_error
&);
1047 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec2
),
1048 "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input" );
1050 // related test case: empty map (indefinite length)
1051 std :: vector
< uint8_t > vec3
{ 0xbf };
1052 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec3
), json :: parse_error
&);
1053 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec3
),
1054 "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input" );
1057 SECTION ( "issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)" )
1059 // original test case
1060 std :: vector
< uint8_t > vec
1062 0xab , 0x98 , 0x98 , 0x98 , 0x98 , 0x98 , 0x98 , 0x98 ,
1063 0x98 , 0x98 , 0x98 , 0x98 , 0x98 , 0x00 , 0x00 , 0x00 ,
1064 0x60 , 0xab , 0x98 , 0x98 , 0x98 , 0x98 , 0x98 , 0x98 ,
1065 0x98 , 0x98 , 0x98 , 0x98 , 0x98 , 0x00 , 0x00 , 0x00 ,
1066 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1067 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1068 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1069 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1070 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1071 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1072 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0xa0 , 0x9f ,
1073 0x9f , 0x97 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1074 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1075 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1076 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1077 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 ,
1078 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60
1082 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec
), json :: parse_error
&);
1083 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec
),
1084 "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98" );
1086 // related test case: nonempty UTF-8 string (indefinite length)
1087 std :: vector
< uint8_t > vec1
{ 0x7f , 0x61 , 0x61 };
1088 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec1
), json :: parse_error
&);
1089 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec1
),
1090 "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input" );
1092 // related test case: nonempty array (indefinite length)
1093 std :: vector
< uint8_t > vec2
{ 0x9f , 0x01 };
1094 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec2
), json :: parse_error
&);
1095 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec2
),
1096 "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input" );
1098 // related test case: nonempty map (indefinite length)
1099 std :: vector
< uint8_t > vec3
{ 0xbf , 0x61 , 0x61 , 0x01 };
1100 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec3
), json :: parse_error
&);
1101 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec3
),
1102 "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input" );
1105 SECTION ( "issue #414 - compare with literal 0)" )
1107 #define CHECK_TYPE(v) \
1108 CHECK((json(v) == (v)));\
1109 CHECK(((v) == json(v)));\
1110 CHECK_FALSE((json(v) != (v)));\
1111 CHECK_FALSE(((v) != json(v)));
1118 CHECK_TYPE ( "" ) // NOLINT(readability-container-size-empty)
1123 SECTION ( "issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)" )
1125 // original test case
1126 std :: vector
< uint8_t > vec1
1128 0x94 , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa ,
1129 0x3a , 0x96 , 0x96 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 ,
1130 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0x71 ,
1131 0xb4 , 0xb4 , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0x3a ,
1132 0x96 , 0x96 , 0xb4 , 0xb4 , 0xfa , 0x94 , 0x94 , 0x61 ,
1133 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0xfa
1137 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec1
), json :: parse_error
&);
1138 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec1
),
1139 "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4" );
1141 // related test case: double-precision
1142 std :: vector
< uint8_t > vec2
1144 0x94 , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa ,
1145 0x3a , 0x96 , 0x96 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 ,
1146 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0xb4 , 0x71 ,
1147 0xb4 , 0xb4 , 0xfa , 0xfa , 0xfa , 0xfa , 0xfa , 0x3a ,
1148 0x96 , 0x96 , 0xb4 , 0xb4 , 0xfa , 0x94 , 0x94 , 0x61 ,
1149 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0x61 , 0xfb
1151 CHECK_THROWS_AS ( _
= json :: from_cbor ( vec2
), json :: parse_error
&);
1152 CHECK_THROWS_WITH ( _
= json :: from_cbor ( vec2
),
1153 "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4" );
1156 SECTION ( "issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)" )
1158 std :: vector
< uint8_t > vec
= { '-' , '0' , '1' , '2' , '2' , '7' , '4' };
1160 CHECK_THROWS_AS ( _
= json :: parse ( vec
), json :: parse_error
&);
1163 SECTION ( "issue #454 - doubles are printed as integers" )
1165 json j
= R
"({" bool_value
":true," double_value
":2.0," int_value
":10," level1
":{" list_value
":[3," hi
",false]," tmp
":5.0}," string_value
":" hello
"})" _json
;
1166 CHECK ( j
[ "double_value" ]. is_number_float ());
1169 #if JSON_USE_IMPLICIT_CONVERSIONS
1170 SECTION ( "issue #464 - VS2017 implicit to std::string conversion fix" )
1179 SECTION ( "issue #465 - roundtrip error while parsing 1000000000000000010E5" )
1181 json j1
= json :: parse ( "1000000000000000010E5" );
1182 std :: string s1
= j1
. dump ();
1183 json j2
= json :: parse ( s1
);
1184 std :: string s2
= j2
. dump ();
1188 #if JSON_USE_IMPLICIT_CONVERSIONS
1189 SECTION ( "issue #473 - inconsistent behavior in conversion to array type" )
1191 json j_array
= { 1 , 2 , 3 , 4 };
1193 json j_null
= nullptr ;
1195 SECTION ( "std::vector" )
1197 auto create
= []( const json
& j
)
1199 std :: vector
< int > v
= j
;
1202 CHECK_NOTHROW ( create ( j_array
));
1203 CHECK_THROWS_AS ( create ( j_number
), json :: type_error
&);
1204 CHECK_THROWS_WITH ( create ( j_number
), "[json.exception.type_error.302] type must be array, but is number" );
1205 CHECK_THROWS_AS ( create ( j_null
), json :: type_error
&);
1206 CHECK_THROWS_WITH ( create ( j_null
), "[json.exception.type_error.302] type must be array, but is null" );
1209 SECTION ( "std::list" )
1211 auto create
= []( const json
& j
)
1213 std :: list
< int > v
= j
;
1216 CHECK_NOTHROW ( create ( j_array
));
1217 CHECK_THROWS_AS ( create ( j_number
), json :: type_error
&);
1218 CHECK_THROWS_WITH ( create ( j_number
), "[json.exception.type_error.302] type must be array, but is number" );
1219 CHECK_THROWS_AS ( create ( j_null
), json :: type_error
&);
1220 CHECK_THROWS_WITH ( create ( j_null
), "[json.exception.type_error.302] type must be array, but is null" );
1223 SECTION ( "std::forward_list" )
1225 auto create
= []( const json
& j
)
1227 std :: forward_list
< int > v
= j
;
1230 CHECK_NOTHROW ( create ( j_array
));
1231 CHECK_THROWS_AS ( create ( j_number
), json :: type_error
&);
1232 CHECK_THROWS_WITH ( create ( j_number
), "[json.exception.type_error.302] type must be array, but is number" );
1233 CHECK_THROWS_AS ( create ( j_null
), json :: type_error
&);
1234 CHECK_THROWS_WITH ( create ( j_null
), "[json.exception.type_error.302] type must be array, but is null" );
1239 SECTION ( "issue #486 - json::value_t can't be a map's key type in VC++ 2015" )
1241 // the code below must compile with MSVC
1242 std :: map
< json :: value_t
, std :: string
> jsonTypes
;
1243 jsonTypes
[ json :: value_t :: array
] = "array" ;
1246 SECTION ( "issue #494 - conversion from vector<bool> to json fails to build" )
1248 std :: vector
< bool > boolVector
= { false , true , false , false };
1250 j
[ "bool_vector" ] = boolVector
;
1252 CHECK ( j
[ "bool_vector" ]. dump () == "[false,true,false,false]" );
1255 SECTION ( "issue #504 - assertion error (OSS-Fuzz 856)" )
1257 std :: vector
< uint8_t > vec1
= { 0xf9 , 0xff , 0xff , 0x4a , 0x3a , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x01 , 0x37 , 0x02 , 0x38 };
1258 json j1
= json :: from_cbor ( vec1
, false );
1260 // step 2: round trip
1261 std :: vector
< uint8_t > vec2
= json :: to_cbor ( j1
);
1263 // parse serialization
1264 json j2
= json :: from_cbor ( vec2
);
1266 // NaN is dumped to "null"
1267 CHECK ( j2
. is_number_float ());
1268 CHECK ( std :: isnan ( j2
. get
< json :: number_float_t
>()));
1269 CHECK ( j2
. dump () == "null" );
1271 // check if serializations match
1272 CHECK ( json :: to_cbor ( j2
) == vec2
);
1275 SECTION ( "issue #512 - use of overloaded operator '<=' is ambiguous" )
1290 CHECK (!( j
[ "a" ] <= 4 ));
1291 CHECK (!( j
[ "a" ] < 4 ));
1292 CHECK (!( j
[ "a" ] >= 6 ));
1293 CHECK (!( j
[ "a" ] > 6 ));
1304 CHECK (!( 4 >= j
[ "a" ]));
1305 CHECK (!( 4 > j
[ "a" ]));
1306 CHECK (!( 6 <= j
[ "a" ]));
1307 CHECK (!( 6 < j
[ "a" ]));
1310 SECTION ( "issue #575 - heap-buffer-overflow (OSS-Fuzz 1400)" )
1313 std :: vector
< uint8_t > vec
= { '"' , ' \\ ' , '"' , 'X' , '"' , '"' };
1314 CHECK_THROWS_AS ( _
= json :: parse ( vec
), json :: parse_error
&);
1317 #if JSON_USE_IMPLICIT_CONVERSIONS
1318 SECTION ( "issue #600 - how does one convert a map in Json back to std::map?" )
1320 SECTION ( "example 1" )
1323 std :: map
< std :: string
, int > m1
{{ "key" , 1 }};
1325 // create and print a JSON from the map
1328 // get the map out of JSON
1329 std :: map
< std :: string
, int > m2
= j
;
1331 // make sure the roundtrip succeeds
1335 SECTION ( "example 2" )
1338 std :: map
< std :: string
, std :: string
> m1
{{ "key" , "val" }};
1340 // create and print a JSON from the map
1343 // get the map out of JSON
1344 std :: map
< std :: string
, std :: string
> m2
= j
;
1346 // make sure the roundtrip succeeds
1352 SECTION ( "issue #602 - BOM not skipped when using json:parse(iterator)" )
1354 std :: string i
= " \xef\xbb\xbf { \n \" foo \" : true \n }" ;
1356 CHECK_NOTHROW ( _
= json :: parse ( i
. begin (), i
. end ()));
1359 #if JSON_USE_IMPLICIT_CONVERSIONS
1360 SECTION ( "issue #702 - conversion from valarray<double> to json fails to build" )
1362 SECTION ( "original example" )
1364 std :: valarray
< double > v
;
1369 SECTION ( "full example" )
1371 std :: valarray
< double > v
= { 1.2 , 2.3 , 3.4 , 4.5 };
1373 std :: valarray
< double > vj
= j
;
1375 CHECK ( j
== json ( vj
));
1376 CHECK ( v
. size () == vj
. size ());
1377 for ( size_t i
= 0 ; i
< v
. size (); ++ i
)
1379 CHECK ( v
[ i
] == vj
[ i
]);
1380 CHECK ( v
[ i
] == j
[ i
]);
1383 CHECK_THROWS_AS ( json (). get
< std :: valarray
< double >>(), json :: type_error
&);
1384 CHECK_THROWS_WITH ( json (). get
< std :: valarray
< double >>(),
1385 "[json.exception.type_error.302] type must be array, but is null" );
1390 SECTION ( "issue #367 - Behavior of operator>> should more closely resemble that of built-in overloads." )
1392 SECTION ( "example 1" )
1394 std :: istringstream
i1_2_3 ( R
"({" first
": " one
" }{" second
": " two
"}3)" );
1402 auto m1
= j1
. get
< std :: map
< std :: string
, std :: string
>>();
1403 auto m2
= j2
. get
< std :: map
< std :: string
, std :: string
>>();
1406 CHECK ( m1
== ( std :: map
< std :: string
, std :: string
> {{ "first" , "one" }} ));
1407 CHECK ( m2
== ( std :: map
< std :: string
, std :: string
> {{ "second" , "two" }} ));
1412 SECTION ( "issue #714 - throw std::ios_base::failure exception when failbit set to true" )
1418 | std :: ios_base :: failbit
1419 | std :: ios_base :: badbit
1420 ); // handle different exceptions as 'file not found', 'permission denied'
1422 is
. open ( TEST_DATA_DIRECTORY
"/regression/working_file.json" );
1424 CHECK_NOTHROW ( _
= nlohmann :: json :: parse ( is
));
1431 | std :: ios_base :: failbit
1432 | std :: ios_base :: badbit
1433 ); // handle different exceptions as 'file not found', 'permission denied'
1435 is
. open ( TEST_DATA_DIRECTORY
"/json_nlohmann_tests/all_unicode.json.cbor" ,
1436 std :: ios_base :: in
| std :: ios_base :: binary
);
1438 CHECK_NOTHROW ( _
= nlohmann :: json :: from_cbor ( is
));
1442 SECTION ( "issue #805 - copy constructor is used with std::initializer_list constructor." )
1446 j
= {{ "nocopy" , n
}};
1447 CHECK ( j
[ "nocopy" ][ "val" ] == 0 );
1450 SECTION ( "issue #838 - incorrect parse error with binary data in keys" )
1452 std :: array
< uint8_t , 28 > key1
= {{ 103 , 92 , 117 , 48 , 48 , 48 , 55 , 92 , 114 , 215 , 126 , 214 , 95 , 92 , 34 , 174 , 40 , 71 , 38 , 174 , 40 , 71 , 38 , 223 , 134 , 247 , 127 , 0 }};
1453 std :: string
key1_str ( reinterpret_cast < char *>( key1
. data ()));
1455 CHECK_THROWS_AS ( j
. dump (), json :: type_error
&);
1456 CHECK_THROWS_WITH ( j
. dump (), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E" );
1459 #if JSON_USE_IMPLICIT_CONVERSIONS
1460 SECTION ( "issue #843 - converting to array not working" )
1463 std :: array
< int , 4 > ar
= {{ 1 , 1 , 1 , 1 }};
1469 SECTION ( "issue #894 - invalid RFC6902 copy operation succeeds" )
1480 auto p1
= R
"([{" op
": " move
",
1481 " from
": " / one
/ two
/ three
",
1482 " path
": " / a
/ b
/ c
"}])" _json
;
1483 CHECK_THROWS_AS ( model
. patch ( p1
), json :: out_of_range
&);
1485 auto p2
= R
"([{" op
": " move
",
1486 " from
": " / one
/ two
/ three
",
1487 " path
": " / a
/ b
/ c
"}])" _json
;
1488 CHECK_THROWS_WITH ( model
. patch ( p2
),
1489 "[json.exception.out_of_range.403] key 'a' not found" );
1491 auto p3
= R
"([{" op
": " copy
",
1492 " from
": " / one
/ two
/ three
",
1493 " path
": " / a
/ b
/ c
"}])" _json
;
1494 CHECK_THROWS_AS ( model
. patch ( p3
), json :: out_of_range
&);
1496 auto p4
= R
"([{" op
": " copy
",
1497 " from
": " / one
/ two
/ three
",
1498 " path
": " / a
/ b
/ c
"}])" _json
;
1499 CHECK_THROWS_WITH ( model
. patch ( p4
),
1500 "[json.exception.out_of_range.403] key 'a' not found" );
1503 SECTION ( "issue #961 - incorrect parsing of indefinite length CBOR strings" )
1505 std :: vector
< uint8_t > v_cbor
=
1514 json j
= json :: from_cbor ( v_cbor
);
1515 CHECK ( j
== "abcd123" );
1518 SECTION ( "issue #962 - Timeout (OSS-Fuzz 6034)" )
1521 std :: vector
< uint8_t > v_ubjson
= { '[' , '$' , 'Z' , '#' , 'L' , 0x78 , 0x28 , 0x00 , 0x68 , 0x28 , 0x69 , 0x69 , 0x17 };
1522 CHECK_THROWS_AS ( _
= json :: from_ubjson ( v_ubjson
), json :: out_of_range
&);
1523 //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1524 // "[json.exception.out_of_range.408] excessive array size: 8658170730974374167");
1527 CHECK_THROWS_AS ( _
= json :: from_ubjson ( v_ubjson
), json :: out_of_range
&);
1528 //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1529 // "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
1532 SECTION ( "issue #971 - Add a SAX parser - late bug" )
1535 const auto * text
= R
"(
1540 " Title
": " View from
15 th Floor
",
1542 " Url
": " http
: //www.example.com/image/481989943",
1547 "IDs" : [ 116 , 943 , 234 , 38793 ]
1552 // define parser callback
1553 json::parser_callback_t cb = [](int /*depth*/, json::parse_event_t event, json & parsed)
1555 // skip object elements with key " Thumbnail
"
1556 return !(event == json::parse_event_t::key && parsed == json(" Thumbnail
"));
1559 // parse (with callback) and serialize JSON
1560 json j_filtered = json::parse(text, cb);
1562 CHECK(j_filtered == R" ({ "Image" :{ "Animated" : false , "Height" : 600 , "IDs" :[ 116 , 943 , 234 , 38793 ], "Title" : "View from 15th Floor" , "Width" : 800 }}) "_json);
1565 SECTION(" issue
#972 - Segmentation fault on G++ when trying to assign json string literal to custom json type ")
1567 my_json foo = R" ([1, 2, 3]) "_json;
1570 SECTION(" issue #977 - Assigning between different json types ")
1572 foo_json lj = ns::foo{3};
1574 CHECK(lj.is_object());
1575 CHECK(lj.size() == 1);
1576 CHECK(lj[" x "] == 3);
1578 nlohmann::json nj = lj; // This line works as expected
1582 #if !defined(JSON_NOEXCEPTION)
1583 TEST_CASE(" regression tests, exceptions dependent ")
1585 SECTION(" issue #1340 - eof not set on exhausted input stream ")
1587 std::stringstream s(" {}{} ");
1591 CHECK_THROWS_AS(s >> j, json::parse_error const&);
1597 /////////////////////////////////////////////////////////////////////
1599 /////////////////////////////////////////////////////////////////////
1601 // the code below fails with Clang on Windows, so we need to exclude it there
1602 #if defined(__clang__) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))
1604 template <typename T> class array {};
1605 template <typename T> class object {};
1606 template <typename T> class string {};
1607 template <typename T> class number_integer {};
1608 template <typename T> class number_unsigned {};
1609 template <typename T> class number_float {};