• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.7.3
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #include "doctest_compatibility.h"
31 DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
32 
33 // for some reason including this after the json header leads to linker errors with VS 2017...
34 #include <locale>
35 
36 #define private public
37 #include <nlohmann/json.hpp>
38 using nlohmann::json;
39 #undef private
40 
41 #include <fstream>
42 #include <sstream>
43 #include <list>
44 #include <cstdio>
45 
46 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
47     #define JSON_HAS_CPP_17
48 #endif
49 
50 #ifdef JSON_HAS_CPP_17
51     #include <variant>
52 #endif
53 
54 #include "fifo_map.hpp"
55 
56 /////////////////////////////////////////////////////////////////////
57 // for #972
58 /////////////////////////////////////////////////////////////////////
59 
60 template<class K, class V, class dummy_compare, class A>
61 using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
62 using my_json = nlohmann::basic_json<my_workaround_fifo_map>;
63 
64 /////////////////////////////////////////////////////////////////////
65 // for #977
66 /////////////////////////////////////////////////////////////////////
67 
68 namespace ns
69 {
70 struct foo
71 {
72     int x;
73 };
74 
75 template <typename, typename SFINAE = void>
76 struct foo_serializer;
77 
78 template<typename T>
79 struct foo_serializer<T, typename std::enable_if<std::is_same<foo, T>::value>::type>
80 {
81     template <typename BasicJsonType>
to_jsonns::foo_serializer82     static void to_json(BasicJsonType& j, const T& value)
83     {
84         j = BasicJsonType{{"x", value.x}};
85     }
86     template <typename BasicJsonType>
from_jsonns::foo_serializer87     static void from_json(const BasicJsonType& j, T& value)     // !!!
88     {
89         nlohmann::from_json(j.at("x"), value.x);
90     }
91 };
92 
93 template<typename T>
94 struct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::value >::type >
95 {
96     template <typename BasicJsonType>
to_jsonns::foo_serializer97     static void to_json(BasicJsonType& j, const T& value) noexcept
98     {
99         ::nlohmann::to_json(j, value);
100     }
101     template <typename BasicJsonType>
from_jsonns::foo_serializer102     static void from_json(const BasicJsonType& j, T& value)   //!!!
103     {
104         ::nlohmann::from_json(j, value);
105     }
106 };
107 }
108 
109 using foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
110       std::uint64_t, double, std::allocator, ns::foo_serializer>;
111 
112 /////////////////////////////////////////////////////////////////////
113 // for #805
114 /////////////////////////////////////////////////////////////////////
115 
116 namespace
117 {
118 struct nocopy
119 {
120     nocopy() = default;
121     nocopy(const nocopy&) = delete;
122 
123     int val = 0;
124 
to_json(json & j,const nocopy & n)125     friend void to_json(json& j, const nocopy& n)
126     {
127         j = {{"val", n.val}};
128     }
129 };
130 
131 struct Data
132 {
133     Data() = default;
Data__anon9ae719c70111::Data134     Data(const std::string& a_, const std::string b_) : a(a_), b(b_) {}
135     std::string a {};
136     std::string b {};
137 };
138 
from_json(const json & j,Data & data)139 void from_json(const json& j, Data& data)
140 {
141     j["a"].get_to(data.a);
142     j["b"].get_to(data.b);
143 }
144 
operator ==(Data const & lhs,Data const & rhs)145 bool operator==(Data const& lhs, Data const& rhs)
146 {
147     return lhs.a == rhs.a && lhs.b == rhs.b;
148 }
149 
150 //bool operator!=(Data const& lhs, Data const& rhs)
151 //{
152 //    return !(lhs == rhs);
153 //}
154 }
155 
156 /////////////////////////////////////////////////////////////////////
157 // for #1021
158 /////////////////////////////////////////////////////////////////////
159 
160 using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
161 
162 /////////////////////////////////////////////////////////////////////
163 // for #1647
164 /////////////////////////////////////////////////////////////////////
165 namespace
166 {
167 struct NonDefaultFromJsonStruct { };
168 
operator ==(NonDefaultFromJsonStruct const &,NonDefaultFromJsonStruct const &)169 inline bool operator== (NonDefaultFromJsonStruct const&, NonDefaultFromJsonStruct const&)
170 {
171     return true;
172 }
173 
174 enum class for_1647 { one, two };
175 
176 NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
177 {
178     {for_1647::one, "one"},
179     {for_1647::two, "two"},
180 })
181 }
182 
183 namespace nlohmann
184 {
185 template <>
186 struct adl_serializer<NonDefaultFromJsonStruct>
187 {
from_jsonnlohmann::adl_serializer188     static NonDefaultFromJsonStruct from_json (json const&) noexcept
189     {
190         return {};
191     }
192 };
193 }
194 
195 /////////////////////////////////////////////////////////////////////
196 // for #1805
197 /////////////////////////////////////////////////////////////////////
198 
199 struct NotSerializableData
200 {
201     int mydata;
202     float myfloat;
203 };
204 
205 
206 TEST_CASE("regression tests")
207 {
208     SECTION("issue #60 - Double quotation mark is not parsed correctly")
209     {
210         SECTION("escape_doublequote")
211         {
212             auto s = "[\"\\\"foo\\\"\"]";
213             json j = json::parse(s);
214             auto expected = R"(["\"foo\""])"_json;
215             CHECK(j == expected);
216         }
217     }
218 
219     SECTION("issue #70 - Handle infinity and NaN cases")
220     {
221         // previously, NAN/INFINITY created a null value; now, the values are
222         // properly stored, but are dumped as "null"
223         SECTION("NAN value")
224         {
225             CHECK(json(NAN).dump() == "null");
226             CHECK(json(json::number_float_t(NAN)).dump() == "null");
227         }
228 
229         SECTION("infinity")
230         {
231             CHECK(json(INFINITY).dump() == "null");
232             CHECK(json(json::number_float_t(INFINITY)).dump() == "null");
233         }
234 
235         // With 3.0.0, the semantics of this changed: NAN and infinity are
236         // stored properly inside the JSON value (no exception or conversion
237         // to null), but are serialized as null.
238         SECTION("NAN value")
239         {
240             json j1 = NAN;
241             CHECK(j1.is_number_float());
242             json::number_float_t f1 = j1;
243             CHECK(std::isnan(f1));
244 
245             json j2 = json::number_float_t(NAN);
246             CHECK(j2.is_number_float());
247             json::number_float_t f2 = j2;
248             CHECK(std::isnan(f2));
249         }
250 
251         SECTION("infinity")
252         {
253             json j1 = INFINITY;
254             CHECK(j1.is_number_float());
255             json::number_float_t f1 = j1;
256             CHECK(not std::isfinite(f1));
257 
258             json j2 = json::number_float_t(INFINITY);
259             CHECK(j2.is_number_float());
260             json::number_float_t f2 = j2;
261             CHECK(not std::isfinite(f2));
262         }
263     }
264 
265     SECTION("pull request #71 - handle enum type")
266     {
267         enum { t = 0, u = 102};
268         json j = json::array();
269         j.push_back(t);
270 
271         // maybe this is not the place to test this?
272         json j2 = u;
273 
274         auto anon_enum_value = j2.get<decltype(u)>();
275         CHECK(u == anon_enum_value);
276 
277         // check if the actual value was stored
278         CHECK(j2 == 102);
279 
280         static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "");
281 
282         j.push_back(json::object(
283         {
284             {"game_type", t}
285         }));
286     }
287 
288     SECTION("issue #76 - dump() / parse() not idempotent")
289     {
290         // create JSON object
291         json fields;
292         fields["one"] = std::string("one");
293         fields["two"] = std::string("two three");
294         fields["three"] = std::string("three \"four\"");
295 
296         // create another JSON object by deserializing the serialization
297         std::string payload = fields.dump();
298         json parsed_fields = json::parse(payload);
299 
300         // check individual fields to match both objects
301         CHECK(parsed_fields["one"] == fields["one"]);
302         CHECK(parsed_fields["two"] == fields["two"]);
303         CHECK(parsed_fields["three"] == fields["three"]);
304 
305         // check individual fields to match original input
306         CHECK(parsed_fields["one"] == std::string("one"));
307         CHECK(parsed_fields["two"] == std::string("two three"));
308         CHECK(parsed_fields["three"] == std::string("three \"four\""));
309 
310         // check equality of the objects
311         CHECK(parsed_fields == fields);
312 
313         // check equality of the serialized objects
314         CHECK(fields.dump() == parsed_fields.dump());
315 
316         // check everything in one line
317         CHECK(fields == json::parse(fields.dump()));
318     }
319 
320     SECTION("issue #82 - lexer::get_number return NAN")
321     {
322         const auto content = R"(
323         {
324             "Test":"Test1",
325             "Number":100,
326             "Foo":42.42
327         })";
328 
329         std::stringstream ss;
330         ss << content;
331         json j;
332         ss >> j;
333 
334         std::string test = j["Test"];
335         CHECK(test == "Test1");
336         int number = j["Number"];
337         CHECK(number == 100);
338         float foo = j["Foo"];
339         CHECK(static_cast<double>(foo) == Approx(42.42));
340     }
341 
342     SECTION("issue #89 - nonstandard integer type")
343     {
344         // create JSON class with nonstandard integer number type
345         using custom_json =
346             nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
347         custom_json j;
348         j["int_1"] = 1;
349         CHECK(j["int_1"] == 1);
350 
351         // tests for correct handling of non-standard integers that overflow the type selected by the user
352 
353         // unsigned integer object creation - expected to wrap and still be stored as an integer
354         j = 4294967296U; // 2^32
355         CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_unsigned));
356         CHECK(j.get<uint32_t>() == 0);  // Wrap
357 
358         // unsigned integer parsing - expected to overflow and be stored as a float
359         j = custom_json::parse("4294967296"); // 2^32
360         CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
361         CHECK(j.get<float>() == 4294967296.0f);
362 
363         // integer object creation - expected to wrap and still be stored as an integer
364         j = -2147483649LL; // -2^31-1
365         CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_integer));
366         CHECK(j.get<int32_t>() == 2147483647);  // Wrap
367 
368         // integer parsing - expected to overflow and be stored as a float with rounding
369         j = custom_json::parse("-2147483649"); // -2^31
370         CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
371         CHECK(j.get<float>() == -2147483650.0f);
372     }
373 
374     SECTION("issue #93 reverse_iterator operator inheritance problem")
375     {
376         {
377             json a = {1, 2, 3};
378             json::reverse_iterator rit = a.rbegin();
379             ++rit;
380             CHECK(*rit == json(2));
381             CHECK(rit.value() == json(2));
382         }
383         {
384             json a = {1, 2, 3};
385             json::reverse_iterator rit = ++a.rbegin();
386             CHECK(*rit == json(2));
387             CHECK(rit.value() == json(2));
388         }
389         {
390             json a = {1, 2, 3};
391             json::reverse_iterator rit = a.rbegin();
392             ++rit;
393             json b = {0, 0, 0};
394             std::transform(rit, a.rend(), b.rbegin(), [](json el)
__anon9ae719c70402(json el) 395             {
396                 return el;
397             });
398             CHECK(b == json({0, 1, 2}));
399         }
400         {
401             json a = {1, 2, 3};
402             json b = {0, 0, 0};
403             std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)
__anon9ae719c70502(json el) 404             {
405                 return el;
406             });
407             CHECK(b == json({0, 1, 2}));
408         }
409     }
410 
411     SECTION("issue #100 - failed to iterator json object with reverse_iterator")
412     {
413         json config =
414         {
415             { "111", 111 },
416             { "112", 112 },
417             { "113", 113 }
418         };
419 
420         std::stringstream ss;
421 
422         for (auto it = config.begin(); it != config.end(); ++it)
423         {
424             ss << it.key() << ": " << it.value() << '\n';
425         }
426 
427         for (auto it = config.rbegin(); it != config.rend(); ++it)
428         {
429             ss << it.key() << ": " << it.value() << '\n';
430         }
431 
432         CHECK(ss.str() == "111: 111\n112: 112\n113: 113\n113: 113\n112: 112\n111: 111\n");
433     }
434 
435     SECTION("issue #101 - binary string causes numbers to be dumped as hex")
436     {
437         int64_t number = 10;
438         std::string bytes{"\x00" "asdf\n", 6};
439         json j;
440         j["int64"] = number;
441         j["binary string"] = bytes;
442         // make sure the number is really printed as decimal "10" and not as
443         // hexadecimal "a"
444         CHECK(j.dump() == "{\"binary string\":\"\\u0000asdf\\n\",\"int64\":10}");
445     }
446 
447     SECTION("issue #111 - subsequent unicode chars")
448     {
449         std::string bytes{0x7, 0x7};
450         json j;
451         j["string"] = bytes;
452         CHECK(j["string"] == "\u0007\u0007");
453     }
454 
455     SECTION("issue #144 - implicit assignment to std::string fails")
456     {
457         json o = {{"name", "value"}};
458 
459         std::string s1 = o["name"];
460         CHECK(s1 == "value");
461 
462         std::string s2;
463         s2 = o["name"];
464 
465         CHECK(s2 == "value");
466     }
467 
468     SECTION("issue #146 - character following a surrogate pair is skipped")
469     {
470         CHECK(json::parse("\"\\ud80c\\udc60abc\"").get<json::string_t>() == u8"\U00013060abc");
471     }
472 
473     SECTION("issue #171 - Cannot index by key of type static constexpr const char*")
474     {
475         json j;
476 
477         // Non-const access with key as "char []"
478         char array_key[] = "Key1";
479         CHECK_NOTHROW(j[array_key] = 1);
480         CHECK(j[array_key] == json(1));
481 
482         // Non-const access with key as "const char[]"
483         const char const_array_key[] = "Key2";
484         CHECK_NOTHROW(j[const_array_key] = 2);
485         CHECK(j[const_array_key] == json(2));
486 
487         // Non-const access with key as "char *"
488         char _ptr_key[] = "Key3";
489         char* ptr_key = &_ptr_key[0];
490         CHECK_NOTHROW(j[ptr_key] = 3);
491         CHECK(j[ptr_key] == json(3));
492 
493         // Non-const access with key as "const char *"
494         const char* const_ptr_key = "Key4";
495         CHECK_NOTHROW(j[const_ptr_key] = 4);
496         CHECK(j[const_ptr_key] == json(4));
497 
498         // Non-const access with key as "static constexpr const char *"
499         static constexpr const char* constexpr_ptr_key = "Key5";
500         CHECK_NOTHROW(j[constexpr_ptr_key] = 5);
501         CHECK(j[constexpr_ptr_key] == json(5));
502 
503         const json j_const = j;
504 
505         // Const access with key as "char []"
506         CHECK(j_const[array_key] == json(1));
507 
508         // Const access with key as "const char[]"
509         CHECK(j_const[const_array_key] == json(2));
510 
511         // Const access with key as "char *"
512         CHECK(j_const[ptr_key] == json(3));
513 
514         // Const access with key as "const char *"
515         CHECK(j_const[const_ptr_key] == json(4));
516 
517         // Const access with key as "static constexpr const char *"
518         CHECK(j_const[constexpr_ptr_key] == json(5));
519     }
520 
521     SECTION("issue #186 miloyip/nativejson-benchmark: floating-point parsing")
522     {
523         json j;
524 
525         j = json::parse("-0.0");
526         CHECK(j.get<double>() == -0.0);
527 
528         j = json::parse("2.22507385850720113605740979670913197593481954635164564e-308");
529         CHECK(j.get<double>() == 2.2250738585072009e-308);
530 
531         j = json::parse("0.999999999999999944488848768742172978818416595458984374");
532         CHECK(j.get<double>() == 0.99999999999999989);
533 
534         j = json::parse("1.00000000000000011102230246251565404236316680908203126");
535         CHECK(j.get<double>() == 1.00000000000000022);
536 
537         j = json::parse("7205759403792793199999e-5");
538         CHECK(j.get<double>() == 72057594037927928.0);
539 
540         j = json::parse("922337203685477529599999e-5");
541         CHECK(j.get<double>() == 9223372036854774784.0);
542 
543         j = json::parse("1014120480182583464902367222169599999e-5");
544         CHECK(j.get<double>() == 10141204801825834086073718800384.0);
545 
546         j = json::parse("5708990770823839207320493820740630171355185151999e-3");
547         CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);
548 
549         // create JSON class with nonstandard float number type
550 
551         // float
552         nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> j_float =
553             1.23e25f;
554         CHECK(j_float.get<float>() == 1.23e25f);
555 
556         // double
557         nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> j_double =
558             1.23e35;
559         CHECK(j_double.get<double>() == 1.23e35);
560 
561         // long double
562         nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>
563         j_long_double = 1.23e45L;
564         CHECK(j_long_double.get<long double>() == 1.23e45L);
565     }
566 
567     SECTION("issue #228 - double values are serialized with commas as decimal points")
568     {
569         json j1a = 2312.42;
570         json j1b = json::parse("2312.42");
571 
572         json j2a = 2342e-2;
573         //issue #230
574         //json j2b = json::parse("2342e-2");
575 
576         json j3a = 10E3;
577         json j3b = json::parse("10E3");
578         json j3c = json::parse("10e3");
579 
580         // class to create a locale that would use a comma for decimals
581         class CommaDecimalSeparator : public std::numpunct<char>
582         {
583           protected:
do_decimal_point() const584             char do_decimal_point() const override
585             {
586                 return ',';
587             }
588 
do_thousands_sep() const589             char do_thousands_sep() const override
590             {
591                 return '.';
592             }
593 
do_grouping() const594             std::string do_grouping() const override
595             {
596                 return "\03";
597             }
598         };
599 
600         // change locale to mess with decimal points
601         auto orig_locale = std::locale::global(std::locale(std::locale(), new CommaDecimalSeparator));
602 
603         CHECK(j1a.dump() == "2312.42");
604         CHECK(j1b.dump() == "2312.42");
605 
606         // check if locale is properly reset
607         std::stringstream ss;
608         ss.imbue(std::locale(std::locale(), new CommaDecimalSeparator));
609         ss << 4712.11;
610         CHECK(ss.str() == "4.712,11");
611         ss << j1a;
612         CHECK(ss.str() == "4.712,112312.42");
613         ss << 47.11;
614         CHECK(ss.str() == "4.712,112312.4247,11");
615 
616         CHECK(j2a.dump() == "23.42");
617         //issue #230
618         //CHECK(j2b.dump() == "23.42");
619 
620         CHECK(j3a.dump() == "10000.0");
621         CHECK(j3b.dump() == "10000.0");
622         CHECK(j3c.dump() == "10000.0");
623         //CHECK(j3b.dump() == "1E04"); // roundtrip error
624         //CHECK(j3c.dump() == "1e04"); // roundtrip error
625 
626         std::locale::global(orig_locale);
627     }
628 
629     SECTION("issue #378 - locale-independent num-to-str")
630     {
631         setlocale(LC_NUMERIC, "de_DE.UTF-8");
632 
633         // verify that dumped correctly with '.' and no grouping
634         const json j1 = 12345.67;
635         CHECK(json(12345.67).dump() == "12345.67");
636         setlocale(LC_NUMERIC, "C");
637     }
638 
639     SECTION("issue #379 - locale-independent str-to-num")
640     {
641         setlocale(LC_NUMERIC, "de_DE.UTF-8");
642 
643         // verify that parsed correctly despite using strtod internally
644         CHECK(json::parse("3.14").get<double>() == 3.14);
645 
646         // check a different code path
647         CHECK(json::parse("1.000000000000000000000000000000000000000000000000000000000000000000000000").get<double>() == 1.0);
648     }
649 
650     SECTION("issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator")
651     {
652         json source = {"a", "b", "c"};
653         json expected = {"a", "b"};
654         json dest;
655 
656         std::copy_n(std::make_move_iterator(source.begin()), 2, std::back_inserter(dest));
657 
658         CHECK(dest == expected);
659     }
660 
661     SECTION("issue #235 - ambiguous overload for 'push_back' and 'operator+='")
662     {
663         json data = {{"key", "value"}};
664         data.push_back({"key2", "value2"});
665         data += {"key3", "value3"};
666 
667         CHECK(data == json({{"key", "value"}, {"key2", "value2"}, {"key3", "value3"}}));
668     }
669 
670     SECTION("issue #269 - diff generates incorrect patch when removing multiple array elements")
671     {
672         json doc = R"( { "arr1": [1, 2, 3, 4] } )"_json;
673         json expected = R"( { "arr1": [1, 2] } )"_json;
674 
675         // check roundtrip
676         CHECK(doc.patch(json::diff(doc, expected)) == expected);
677     }
678 
679     SECTION("issue #283 - value() does not work with _json_pointer types")
680     {
681         json j =
682         {
683             {"object", {{"key1", 1}, {"key2", 2}}},
684         };
685 
686         int at_integer = j.at("/object/key2"_json_pointer);
687         int val_integer = j.value("/object/key2"_json_pointer, 0);
688 
689         CHECK(at_integer == val_integer);
690     }
691 
692     SECTION("issue #304 - Unused variable warning")
693     {
694         // code triggered a "warning: unused variable" warning and is left
695         // here to avoid the warning in the future
696         json object;
697         json patch = json::array();
698         object = object.patch(patch);
699     }
700 
701     SECTION("issue #306 - Parsing fails without space at end of file")
702     {
703         for (auto filename :
704                 {
705                     "test/data/regression/broken_file.json",
706                     "test/data/regression/working_file.json"
707                 })
708         {
709             CAPTURE(filename)
710             json j;
711             std::ifstream f(filename);
712             CHECK_NOTHROW(f >> j);
713         }
714     }
715 
716     SECTION("issue #310 - make json_benchmarks no longer working in 2.0.4")
717     {
718         for (auto filename :
719                 {
720                     "test/data/regression/floats.json",
721                     "test/data/regression/signed_ints.json",
722                     "test/data/regression/unsigned_ints.json",
723                     "test/data/regression/small_signed_ints.json"
724                 })
725         {
726             CAPTURE(filename)
727             json j;
728             std::ifstream f(filename);
729             CHECK_NOTHROW(f >> j);
730         }
731     }
732 
733     SECTION("issue #323 - add nested object capabilities to pointers")
734     {
735         json j;
736         j["/this/that/2"_json_pointer] = 27;
737         CHECK(j == json({{"this", {{"that", {nullptr, nullptr, 27}}}}}));
738     }
739 
740     SECTION("issue #329 - serialized value not always can be parsed")
741     {
742         json _;
743         CHECK_THROWS_AS(_ = json::parse("22e2222"), json::out_of_range&);
744         CHECK_THROWS_WITH(_ = json::parse("22e2222"),
745                           "[json.exception.out_of_range.406] number overflow parsing '22e2222'");
746     }
747 
748     SECTION("issue #360 - Loss of precision when serializing <double>")
749     {
750         auto check_roundtrip = [](double number)
__anon9ae719c70602(double number) 751         {
752             CAPTURE(number)
753 
754             json j = number;
755             CHECK(j.is_number_float());
756 
757             std::stringstream ss;
758             ss << j;
759 
760             CHECK_NOTHROW(ss >> j);
761             CHECK(j.is_number_float());
762             CHECK(j.get<json::number_float_t>() == number);
763         };
764 
765         check_roundtrip(100000000000.1236);
766         check_roundtrip((std::numeric_limits<json::number_float_t>::max)());
767 
768         // Some more numbers which fail to roundtrip when serialized with digits10 significand digits (instead of max_digits10)
769         check_roundtrip(1.541888611948064e-17);
770         check_roundtrip(5.418771028591015e-16);
771         check_roundtrip(9.398685592608595e-15);
772         check_roundtrip(8.826843952762347e-14);
773         check_roundtrip(8.143291313475335e-13);
774         check_roundtrip(4.851328172762508e-12);
775         check_roundtrip(6.677850998084358e-11);
776         check_roundtrip(3.995398518174525e-10);
777         check_roundtrip(1.960452605645124e-9);
778         check_roundtrip(3.551812586302883e-8);
779         check_roundtrip(2.947988411689261e-7);
780         check_roundtrip(8.210166748056192e-6);
781         check_roundtrip(6.104889704266753e-5);
782         check_roundtrip(0.0008629954631330876);
783         check_roundtrip(0.004936993881051611);
784         check_roundtrip(0.08309725102608073);
785         check_roundtrip(0.5210494268499783);
786         check_roundtrip(6.382927930939767);
787         check_roundtrip(59.94947245358671);
788         check_roundtrip(361.0838651266122);
789         check_roundtrip(4678.354596181877);
790         check_roundtrip(61412.17658956043);
791         check_roundtrip(725696.0799057782);
792         check_roundtrip(2811732.583399828);
793         check_roundtrip(30178351.07533605);
794         check_roundtrip(689684880.3235844);
795         check_roundtrip(5714887673.555147);
796         check_roundtrip(84652038821.18808);
797         check_roundtrip(156510583431.7721);
798         check_roundtrip(5938450569021.732);
799         check_roundtrip(83623297654460.33);
800         check_roundtrip(701466573254773.6);
801         check_roundtrip(1369013370304513);
802         check_roundtrip(96963648023094720);
803         check_roundtrip(3.478237409280108e+17);
804     }
805 
806     SECTION("issue #366 - json::parse on failed stream gets stuck")
807     {
808         std::ifstream f("file_not_found.json");
809         json _;
810         CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
811         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");
812     }
813 
814     SECTION("issue #367 - calling stream at EOF")
815     {
816         std::stringstream ss;
817         json j;
818         ss << "123";
819         CHECK_NOTHROW(ss >> j);
820 
821         // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
822         // ss is not at EOF; this yielded an error before the fix
823         // (threw basic_string::append). No, it should just throw
824         // a parse error because of the EOF.
825         CHECK_THROWS_AS(ss >> j, json::parse_error&);
826         CHECK_THROWS_WITH(ss >> j,
827                           "[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");
828     }
829 
830     SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
831     {
832         SECTION("(empty)")
833         {
834             std::stringstream ss;
835             json j;
836             CHECK_THROWS_AS(ss >> j, json::parse_error&);
837             CHECK_THROWS_WITH(ss >> j,
838                               "[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");
839         }
840 
841         SECTION("(whitespace)")
842         {
843             std::stringstream ss;
844             ss << "   ";
845             json j;
846             CHECK_THROWS_AS(ss >> j, json::parse_error&);
847             CHECK_THROWS_WITH(ss >> j,
848                               "[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");
849         }
850 
851         SECTION("one value")
852         {
853             std::stringstream ss;
854             ss << "111";
855             json j;
856             CHECK_NOTHROW(ss >> j);
857             CHECK(j == 111);
858 
859             CHECK_THROWS_AS(ss >> j, json::parse_error&);
860             CHECK_THROWS_WITH(ss >> j,
861                               "[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");
862         }
863 
864         SECTION("one value + whitespace")
865         {
866             std::stringstream ss;
867             ss << "222 \t\n";
868             json j;
869             CHECK_NOTHROW(ss >> j);
870             CHECK(j == 222);
871 
872             CHECK_THROWS_AS(ss >> j, json::parse_error&);
873             CHECK_THROWS_WITH(ss >> j,
874                               "[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");
875         }
876 
877         SECTION("whitespace + one value")
878         {
879             std::stringstream ss;
880             ss << "\n\t 333";
881             json j;
882             CHECK_NOTHROW(ss >> j);
883             CHECK(j == 333);
884 
885             CHECK_THROWS_AS(ss >> j, json::parse_error&);
886             CHECK_THROWS_WITH(ss >> j,
887                               "[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");
888         }
889 
890         SECTION("three values")
891         {
892             std::stringstream ss;
893             ss << " 111 \n222\n \n  333";
894             json j;
895             CHECK_NOTHROW(ss >> j);
896             CHECK(j == 111);
897             CHECK_NOTHROW(ss >> j);
898             CHECK(j == 222);
899             CHECK_NOTHROW(ss >> j);
900             CHECK(j == 333);
901 
902             CHECK_THROWS_AS(ss >> j, json::parse_error&);
903             CHECK_THROWS_WITH(ss >> j,
904                               "[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");
905         }
906 
907         SECTION("literals without whitespace")
908         {
909             std::stringstream ss;
910             ss << "truefalsenull\"\"";
911             json j;
912             CHECK_NOTHROW(ss >> j);
913             CHECK(j == true);
914             CHECK_NOTHROW(ss >> j);
915             CHECK(j == false);
916             CHECK_NOTHROW(ss >> j);
917             CHECK(j == nullptr);
918             CHECK_NOTHROW(ss >> j);
919             CHECK(j == "");
920 
921             CHECK_THROWS_AS(ss >> j, json::parse_error&);
922             CHECK_THROWS_WITH(ss >> j,
923                               "[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");
924         }
925 
926         SECTION("example from #529")
927         {
928             std::stringstream ss;
929             ss << "{\n    \"one\"   : 1,\n    \"two\"   : 2\n}\n{\n    \"three\" : 3\n}";
930             json j;
931             CHECK_NOTHROW(ss >> j);
932             CHECK(j == json({{"one", 1}, {"two", 2}}));
933             CHECK_NOTHROW(ss >> j);
934             CHECK(j == json({{"three", 3}}));
935 
936             CHECK_THROWS_AS(ss >> j, json::parse_error&);
937             CHECK_THROWS_WITH(ss >> j,
938                               "[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");
939         }
940 
941         SECTION("second example from #529")
942         {
943             std::string str = "{\n\"one\"   : 1,\n\"two\"   : 2\n}\n{\n\"three\" : 3\n}";
944 
945             {
946                 std::ofstream file("test.json");
947                 file << str;
948             }
949 
950             std::ifstream stream("test.json", std::ifstream::in);
951             json val;
952 
953             size_t i = 0;
954             while (stream.peek() != EOF)
955             {
956                 CAPTURE(i)
957                 CHECK_NOTHROW(stream >> val);
958 
959                 CHECK(i < 2);
960 
961                 if (i == 0)
962                 {
963                     CHECK(val == json({{"one", 1}, {"two", 2}}));
964                 }
965 
966                 if (i == 1)
967                 {
968                     CHECK(val == json({{"three", 3}}));
969                 }
970 
971                 ++i;
972             }
973 
974             std::remove("test.json");
975         }
976     }
977 
978     SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
979     {
980         // original test case
981         json j1 = json::parse("-9223372036854775808");
982         CHECK(j1.is_number_integer());
983         CHECK(j1.get<json::number_integer_t>() == INT64_MIN);
984 
985         // edge case (+1; still an integer)
986         json j2 = json::parse("-9223372036854775807");
987         CHECK(j2.is_number_integer());
988         CHECK(j2.get<json::number_integer_t>() == INT64_MIN + 1);
989 
990         // edge case (-1; overflow -> floats)
991         json j3 = json::parse("-9223372036854775809");
992         CHECK(j3.is_number_float());
993     }
994 
995     SECTION("issue #380 - bug in overflow detection when parsing integers")
996     {
997         json j = json::parse("166020696663385964490");
998         CHECK(j.is_number_float());
999         CHECK(j.get<json::number_float_t>() == 166020696663385964490.0);
1000     }
1001 
1002     SECTION("issue #405 - Heap-buffer-overflow (OSS-Fuzz issue 342)")
1003     {
1004         // original test case
1005         std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
1006         json _;
1007         CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);
1008         CHECK_THROWS_WITH(_ = json::from_cbor(vec),
1009                           "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input");
1010     }
1011 
1012     SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
1013     {
1014         json _;
1015 
1016         // original test case: incomplete float64
1017         std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};
1018         CHECK_THROWS_AS(_ = json::from_msgpack(vec1), json::parse_error&);
1019         CHECK_THROWS_WITH(_ = json::from_msgpack(vec1),
1020                           "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
1021 
1022         // related test case: incomplete float32
1023         std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};
1024         CHECK_THROWS_AS(_ = json::from_msgpack(vec2), json::parse_error&);
1025         CHECK_THROWS_WITH(_ = json::from_msgpack(vec2),
1026                           "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
1027 
1028         // related test case: incomplete Half-Precision Float (CBOR)
1029         std::vector<uint8_t> vec3 {0xf9, 0x8f};
1030         CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);
1031         CHECK_THROWS_WITH(_ = json::from_cbor(vec3),
1032                           "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
1033 
1034         // related test case: incomplete Single-Precision Float (CBOR)
1035         std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
1036         CHECK_THROWS_AS(_ = json::from_cbor(vec4), json::parse_error&);
1037         CHECK_THROWS_WITH(_ = json::from_cbor(vec4),
1038                           "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
1039 
1040         // related test case: incomplete Double-Precision Float (CBOR)
1041         std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
1042         CHECK_THROWS_AS(_ = json::from_cbor(vec5), json::parse_error&);
1043         CHECK_THROWS_WITH(_ = json::from_cbor(vec5),
1044                           "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
1045     }
1046 
1047     SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
1048     {
1049         json _;
1050 
1051         // original test case
1052         std::vector<uint8_t> vec1 {0x87};
1053         CHECK_THROWS_AS(_ = json::from_msgpack(vec1), json::parse_error&);
1054         CHECK_THROWS_WITH(_ = json::from_msgpack(vec1),
1055                           "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input");
1056 
1057         // more test cases for MessagePack
1058         for (auto b :
1059                 {
1060                     0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, // fixmap
1061                     0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // fixarray
1062                     0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // fixstr
1063                     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
1064                 })
1065         {
1066             std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
1067             CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);
1068         }
1069 
1070         // more test cases for CBOR
1071         for (auto b :
1072                 {
1073                     0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
1074                     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // UTF-8 string
1075                     0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
1076                     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, // array
1077                     0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
1078                     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7 // map
1079                 })
1080         {
1081             std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
1082             CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);
1083         }
1084 
1085         // special case: empty input
1086         std::vector<uint8_t> vec2;
1087         CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);
1088         CHECK_THROWS_WITH(_ = json::from_cbor(vec2),
1089                           "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input");
1090         CHECK_THROWS_AS(_ = json::from_msgpack(vec2), json::parse_error&);
1091         CHECK_THROWS_WITH(_ = json::from_msgpack(vec2),
1092                           "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input");
1093     }
1094 
1095     SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
1096     {
1097         json _;
1098 
1099         // original test case: empty UTF-8 string (indefinite length)
1100         std::vector<uint8_t> vec1 {0x7f};
1101         CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);
1102         CHECK_THROWS_WITH(_ = json::from_cbor(vec1),
1103                           "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
1104 
1105         // related test case: empty array (indefinite length)
1106         std::vector<uint8_t> vec2 {0x9f};
1107         CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);
1108         CHECK_THROWS_WITH(_ = json::from_cbor(vec2),
1109                           "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input");
1110 
1111         // related test case: empty map (indefinite length)
1112         std::vector<uint8_t> vec3 {0xbf};
1113         CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);
1114         CHECK_THROWS_WITH(_ = json::from_cbor(vec3),
1115                           "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
1116     }
1117 
1118     SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
1119     {
1120         // original test case
1121         std::vector<uint8_t> vec
1122         {
1123             0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
1124             0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
1125             0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
1126             0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
1127             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1128             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1129             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1130             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1131             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1132             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1133             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,
1134             0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1135             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1136             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1137             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1138             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1139             0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
1140         };
1141 
1142         json _;
1143         CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);
1144         CHECK_THROWS_WITH(_ = json::from_cbor(vec),
1145                           "[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");
1146 
1147         // related test case: nonempty UTF-8 string (indefinite length)
1148         std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
1149         CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);
1150         CHECK_THROWS_WITH(_ = json::from_cbor(vec1),
1151                           "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input");
1152 
1153         // related test case: nonempty array (indefinite length)
1154         std::vector<uint8_t> vec2 {0x9f, 0x01};
1155         CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);
1156         CHECK_THROWS_WITH(_ = json::from_cbor(vec2),
1157                           "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
1158 
1159         // related test case: nonempty map (indefinite length)
1160         std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
1161         CHECK_THROWS_AS(_ = json::from_cbor(vec3), json::parse_error&);
1162         CHECK_THROWS_WITH(_ = json::from_cbor(vec3),
1163                           "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input");
1164     }
1165 
1166     SECTION("issue #414 - compare with literal 0)")
1167     {
1168 #define CHECK_TYPE(v) \
1169     CHECK((json(v) == v));\
1170     CHECK((v == json(v)));\
1171     CHECK_FALSE((json(v) != v));\
1172     CHECK_FALSE((v != json(v)));
1173 
1174         CHECK_TYPE(nullptr)
1175         CHECK_TYPE(0)
1176         CHECK_TYPE(0u)
1177         CHECK_TYPE(0L)
1178         CHECK_TYPE(0.0)
1179         CHECK_TYPE("")
1180 
1181 #undef CHECK_TYPE
1182     }
1183 
1184     SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
1185     {
1186         // original test case
1187         std::vector<uint8_t> vec1
1188         {
1189             0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
1190             0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
1191             0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
1192             0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
1193             0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
1194             0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
1195         };
1196 
1197         json _;
1198         CHECK_THROWS_AS(_ = json::from_cbor(vec1), json::parse_error&);
1199         CHECK_THROWS_WITH(_ = json::from_cbor(vec1),
1200                           "[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");
1201 
1202         // related test case: double-precision
1203         std::vector<uint8_t> vec2
1204         {
1205             0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
1206             0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
1207             0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
1208             0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
1209             0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
1210             0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
1211         };
1212         CHECK_THROWS_AS(_ = json::from_cbor(vec2), json::parse_error&);
1213         CHECK_THROWS_WITH(_ = json::from_cbor(vec2),
1214                           "[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");
1215     }
1216 
1217     SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
1218     {
1219         std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'};
1220         json _;
1221         CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
1222     }
1223 
1224     SECTION("issue #454 - doubles are printed as integers")
1225     {
1226         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;
1227         CHECK(j["double_value"].is_number_float());
1228     }
1229 
1230     SECTION("issue #464 - VS2017 implicit to std::string conversion fix")
1231     {
1232         json v = "test";
1233         std::string test;
1234         test = v;
1235         CHECK(v == "test");
1236     }
1237 
1238     SECTION("issue #465 - roundtrip error while parsing 1000000000000000010E5")
1239     {
1240         json j1 = json::parse("1000000000000000010E5");
1241         std::string s1 = j1.dump();
1242         json j2 = json::parse(s1);
1243         std::string s2 = j2.dump();
1244         CHECK(s1 == s2);
1245     }
1246 
1247     SECTION("issue #473 - inconsistent behavior in conversion to array type")
1248     {
1249         json j_array = {1, 2, 3, 4};
1250         json j_number = 42;
1251         json j_null = nullptr;
1252 
1253         SECTION("std::vector")
1254         {
1255             auto create = [](const json & j)
__anon9ae719c70702(const json & j) 1256             {
1257                 std::vector<int> v = j;
1258             };
1259 
1260             CHECK_NOTHROW(create(j_array));
1261             CHECK_THROWS_AS(create(j_number), json::type_error&);
1262             CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
1263             CHECK_THROWS_AS(create(j_null), json::type_error&);
1264             CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
1265         }
1266 
1267         SECTION("std::list")
1268         {
1269             auto create = [](const json & j)
__anon9ae719c70802(const json & j) 1270             {
1271                 std::list<int> v = j;
1272             };
1273 
1274             CHECK_NOTHROW(create(j_array));
1275             CHECK_THROWS_AS(create(j_number), json::type_error&);
1276             CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
1277             CHECK_THROWS_AS(create(j_null), json::type_error&);
1278             CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
1279         }
1280 
1281         SECTION("std::forward_list")
1282         {
1283             auto create = [](const json & j)
__anon9ae719c70902(const json & j) 1284             {
1285                 std::forward_list<int> v = j;
1286             };
1287 
1288             CHECK_NOTHROW(create(j_array));
1289             CHECK_THROWS_AS(create(j_number), json::type_error&);
1290             CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
1291             CHECK_THROWS_AS(create(j_null), json::type_error&);
1292             CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
1293         }
1294     }
1295 
1296     SECTION("issue #486 - json::value_t can't be a map's key type in VC++ 2015")
1297     {
1298         // the code below must compile with MSVC
1299         std::map<json::value_t, std::string> jsonTypes ;
1300         jsonTypes[json::value_t::array] = "array";
1301     }
1302 
1303     SECTION("issue #494 - conversion from vector<bool> to json fails to build")
1304     {
1305         std::vector<bool> boolVector = {false, true, false, false};
1306         json j;
1307         j["bool_vector"] = boolVector;
1308 
1309         CHECK(j["bool_vector"].dump() == "[false,true,false,false]");
1310     }
1311 
1312     SECTION("issue #504 - assertion error (OSS-Fuzz 856)")
1313     {
1314         std::vector<uint8_t> vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};
1315         json j1 = json::from_cbor(vec1, false);
1316 
1317         // step 2: round trip
1318         std::vector<uint8_t> vec2 = json::to_cbor(j1);
1319 
1320         // parse serialization
1321         json j2 = json::from_cbor(vec2);
1322 
1323         // NaN is dumped to "null"
1324         CHECK(j2.is_number_float());
1325         CHECK(std::isnan(j2.get<json::number_float_t>()));
1326         CHECK(j2.dump() == "null");
1327 
1328         // check if serializations match
1329         CHECK(json::to_cbor(j2) == vec2);
1330     }
1331 
1332     SECTION("issue #512 - use of overloaded operator '<=' is ambiguous")
1333     {
1334         json j;
1335         j["a"] = 5;
1336 
1337         // json op scalar
1338         CHECK(j["a"] == 5);
1339         CHECK(j["a"] != 4);
1340 
1341         CHECK(j["a"] <= 7);
1342         CHECK(j["a"] <  7);
1343         CHECK(j["a"] >= 3);
1344         CHECK(j["a"] >  3);
1345 
1346 
1347         CHECK(not(j["a"] <= 4));
1348         CHECK(not(j["a"] <  4));
1349         CHECK(not(j["a"] >= 6));
1350         CHECK(not(j["a"] >  6));
1351 
1352         // scalar op json
1353         CHECK(5 == j["a"]);
1354         CHECK(4 != j["a"]);
1355 
1356         CHECK(7 >= j["a"]);
1357         CHECK(7 >  j["a"]);
1358         CHECK(3 <= j["a"]);
1359         CHECK(3 <  j["a"]);
1360 
1361         CHECK(not(4 >= j["a"]));
1362         CHECK(not(4 >  j["a"]));
1363         CHECK(not(6 <= j["a"]));
1364         CHECK(not(6 <  j["a"]));
1365     }
1366 
1367     SECTION("issue #575 - heap-buffer-overflow (OSS-Fuzz 1400)")
1368     {
1369         json _;
1370         std::vector<uint8_t> vec = {'"', '\\', '"', 'X', '"', '"'};
1371         CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
1372     }
1373 
1374     SECTION("issue #600 - how does one convert a map in Json back to std::map?")
1375     {
1376         SECTION("example 1")
1377         {
1378             // create a map
1379             std::map<std::string, int> m1 {{"key", 1}};
1380 
1381             // create and print a JSON from the map
1382             json j = m1;
1383 
1384             // get the map out of JSON
1385             std::map<std::string, int> m2 = j;
1386 
1387             // make sure the roundtrip succeeds
1388             CHECK(m1 == m2);
1389         }
1390 
1391         SECTION("example 2")
1392         {
1393             // create a map
1394             std::map<std::string, std::string> m1 {{"key", "val"}};
1395 
1396             // create and print a JSON from the map
1397             json j = m1;
1398 
1399             // get the map out of JSON
1400             std::map<std::string, std::string> m2 = j;
1401 
1402             // make sure the roundtrip succeeds
1403             CHECK(m1 == m2);
1404         }
1405     }
1406 
1407     SECTION("issue #602 - BOM not skipped when using json:parse(iterator)")
1408     {
1409         std::string i = "\xef\xbb\xbf{\n   \"foo\": true\n}";
1410         json _;
1411         CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));
1412     }
1413 
1414     SECTION("issue #702 - conversion from valarray<double> to json fails to build")
1415     {
1416         SECTION("original example")
1417         {
1418             std::valarray<double> v;
1419             nlohmann::json j;
1420             j["test"] = v;
1421         }
1422 
1423         SECTION("full example")
1424         {
1425             std::valarray<double> v = {1.2, 2.3, 3.4, 4.5};
1426             json j = v;
1427             std::valarray<double> vj = j;
1428 
1429             CHECK(j == json(vj));
1430             CHECK(v.size() == vj.size());
1431             for (size_t i = 0; i < v.size(); ++i)
1432             {
1433                 CHECK(v[i] == vj[i]);
1434                 CHECK(v[i] == j[i]);
1435             }
1436 
1437             CHECK_THROWS_AS(json().get<std::valarray<double>>(), json::type_error&);
1438             CHECK_THROWS_WITH(json().get<std::valarray<double>>(),
1439                               "[json.exception.type_error.302] type must be array, but is null");
1440         }
1441     }
1442 
1443     SECTION("issue #367 - Behavior of operator>> should more closely resemble that of built-in overloads.")
1444     {
1445         SECTION("example 1")
1446         {
1447             std::istringstream i1_2_3( "{\"first\": \"one\" }{\"second\": \"two\"}3" );
1448             json j1, j2, j3;
1449             i1_2_3 >> j1;
1450             i1_2_3 >> j2;
1451             i1_2_3 >> j3;
1452 
1453             std::map<std::string, std::string> m1 = j1;
1454             std::map<std::string, std::string> m2 = j2;
1455             int i3 = j3;
1456 
1457             CHECK( m1 == ( std::map<std::string, std::string> {{ "first",  "one" }} ));
1458             CHECK( m2 == ( std::map<std::string, std::string> {{ "second", "two" }} ));
1459             CHECK( i3 == 3 );
1460         }
1461     }
1462 
1463     SECTION("issue #714 - throw std::ios_base::failure exception when failbit set to true")
1464     {
1465         {
1466             std::ifstream is;
1467             is.exceptions(
1468                 is.exceptions()
1469                 | std::ios_base::failbit
1470                 | std::ios_base::badbit
1471             ); // handle different exceptions as 'file not found', 'permission denied'
1472 
1473             is.open("test/data/regression/working_file.json");
1474             json _;
1475             CHECK_NOTHROW(_ = nlohmann::json::parse(is));
1476         }
1477 
1478         {
1479             std::ifstream is;
1480             is.exceptions(
1481                 is.exceptions()
1482                 | std::ios_base::failbit
1483                 | std::ios_base::badbit
1484             ); // handle different exceptions as 'file not found', 'permission denied'
1485 
1486             is.open("test/data/json_nlohmann_tests/all_unicode.json.cbor",
1487                     std::ios_base::in | std::ios_base::binary);
1488             json _;
1489             CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));
1490         }
1491     }
1492 
1493     SECTION("issue #805 - copy constructor is used with std::initializer_list constructor.")
1494     {
1495         nocopy n;
1496         json j;
1497         j = {{"nocopy", n}};
1498         CHECK(j["nocopy"]["val"] == 0);
1499     }
1500 
1501     SECTION("issue #838 - incorrect parse error with binary data in keys")
1502     {
1503         uint8_t 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 };
1504         std::string key1_str(key1, key1 + sizeof(key1) / sizeof(key1[0]));
1505         json j = key1_str;
1506         CHECK_THROWS_AS(j.dump(), json::type_error&);
1507         CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E");
1508     }
1509 
1510     SECTION("issue #843 - converting to array not working")
1511     {
1512         json j;
1513         std::array<int, 4> ar = {{1, 1, 1, 1}};
1514         j = ar;
1515         ar = j;
1516     }
1517 
1518     SECTION("issue #894 - invalid RFC6902 copy operation succeeds")
1519     {
1520         auto model = R"({
1521             "one": {
1522                 "two": {
1523                     "three": "hello",
1524                     "four": 42
1525                 }
1526             }
1527         })"_json;
1528 
1529         auto p1 = R"([{"op": "move",
1530                        "from": "/one/two/three",
1531                        "path": "/a/b/c"}])"_json;
1532         CHECK_THROWS_AS(model.patch(p1), json::out_of_range&);
1533 
1534         auto p2 = R"([{"op": "move",
1535                        "from": "/one/two/three",
1536                        "path": "/a/b/c"}])"_json;
1537         CHECK_THROWS_WITH(model.patch(p2),
1538                           "[json.exception.out_of_range.403] key 'a' not found");
1539 
1540         auto p3 = R"([{"op": "copy",
1541                        "from": "/one/two/three",
1542                        "path": "/a/b/c"}])"_json;
1543         CHECK_THROWS_AS(model.patch(p3), json::out_of_range&);
1544 
1545         auto p4 = R"([{"op": "copy",
1546                                  "from": "/one/two/three",
1547                                  "path": "/a/b/c"}])"_json;
1548         CHECK_THROWS_WITH(model.patch(p4),
1549                           "[json.exception.out_of_range.403] key 'a' not found");
1550     }
1551 
1552     SECTION("issue #961 - incorrect parsing of indefinite length CBOR strings")
1553     {
1554         std::vector<uint8_t> v_cbor =
1555         {
1556             0x7F,
1557             0x64,
1558             'a', 'b', 'c', 'd',
1559             0x63,
1560             '1', '2', '3',
1561             0xFF
1562         };
1563         json j = json::from_cbor(v_cbor);
1564         CHECK(j == "abcd123");
1565     }
1566 
1567     SECTION("issue #962 - Timeout (OSS-Fuzz 6034)")
1568     {
1569         json _;
1570         std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
1571         CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1572         //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1573         //                  "[json.exception.out_of_range.408] excessive array size: 8658170730974374167");
1574 
1575         v_ubjson[0] = '{';
1576         CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1577         //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1578         //                  "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
1579     }
1580 
1581     SECTION("issue #971 - Add a SAX parser - late bug")
1582     {
1583         // a JSON text
1584         auto text = R"(
1585     {
1586         "Image": {
1587             "Width":  800,
1588             "Height": 600,
1589             "Title":  "View from 15th Floor",
1590             "Thumbnail": {
1591                 "Url":    "http://www.example.com/image/481989943",
1592                 "Height": 125,
1593                 "Width":  100
1594             },
1595             "Animated" : false,
1596             "IDs": [116, 943, 234, 38793]
1597         }
1598     }
1599     )";
1600 
1601         // define parser callback
1602         json::parser_callback_t cb = [](int /*depth*/, json::parse_event_t event, json & parsed)
__anon9ae719c70a02(int , json::parse_event_t event, json & parsed) 1603         {
1604             // skip object elements with key "Thumbnail"
1605             if (event == json::parse_event_t::key and parsed == json("Thumbnail"))
1606             {
1607                 return false;
1608             }
1609             else
1610             {
1611                 return true;
1612             }
1613         };
1614 
1615         // parse (with callback) and serialize JSON
1616         json j_filtered = json::parse(text, cb);
1617 
1618         CHECK(j_filtered == R"({"Image":{"Animated":false,"Height":600,"IDs":[116,943,234,38793], "Title":"View from 15th Floor","Width":800}})"_json);
1619     }
1620 
1621     SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
1622     {
1623         my_json foo = R"([1, 2, 3])"_json;
1624     }
1625 
1626     SECTION("issue #977 - Assigning between different json types")
1627     {
1628         foo_json lj = ns::foo{3};
1629         ns::foo ff = lj;
1630         CHECK(lj.is_object());
1631         CHECK(lj.size() == 1);
1632         CHECK(lj["x"] == 3);
1633         CHECK(ff.x == 3);
1634         nlohmann::json nj = lj;                // This line works as expected
1635     }
1636 
1637     SECTION("issue #1001 - Fix memory leak during parser callback")
1638     {
1639         auto geojsonExample = R"(
1640           { "type": "FeatureCollection",
1641             "features": [
1642               { "type": "Feature",
1643                 "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
1644                 "properties": {"prop0": "value0"}
1645                 },
1646               { "type": "Feature",
1647                 "geometry": {
1648                   "type": "LineString",
1649                   "coordinates": [
1650                     [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
1651                     ]
1652                   },
1653                 "properties": {
1654                   "prop0": "value0",
1655                   "prop1": 0.0
1656                   }
1657                 },
1658               { "type": "Feature",
1659                  "geometry": {
1660                    "type": "Polygon",
1661                    "coordinates": [
1662                      [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
1663                        [100.0, 1.0], [100.0, 0.0] ]
1664                      ]
1665                  },
1666                  "properties": {
1667                    "prop0": "value0",
1668                    "prop1": {"this": "that"}
1669                    }
1670                  }
1671                ]
1672              })";
1673 
1674         json::parser_callback_t cb = [&](int, json::parse_event_t event, json & parsed)
__anon9ae719c70b02(int, json::parse_event_t event, json & parsed) 1675         {
1676             // skip uninteresting events
1677             if (event == json::parse_event_t::value and !parsed.is_primitive())
1678             {
1679                 return false;
1680             }
1681 
1682             switch (event)
1683             {
1684                 case json::parse_event_t::key:
1685                     {
1686                         return true;
1687                     }
1688                 case json::parse_event_t::value:
1689                     {
1690                         return false;
1691                     }
1692                 case json::parse_event_t::object_start:
1693                     {
1694                         return true;
1695                     }
1696                 case json::parse_event_t::object_end:
1697                     {
1698                         return false;
1699                     }
1700                 case json::parse_event_t::array_start:
1701                     {
1702                         return true;
1703                     }
1704                 case json::parse_event_t::array_end:
1705                     {
1706                         return false;
1707                     }
1708 
1709                 default:
1710                     {
1711                         return true;
1712                     }
1713             }
1714         };
1715 
1716         auto j = json::parse(geojsonExample, cb, true);
1717         CHECK(j == json());
1718     }
1719 
1720     SECTION("issue #1021 - to/from_msgpack only works with standard typization")
1721     {
1722         float_json j = 1000.0;
1723         CHECK(float_json::from_cbor(float_json::to_cbor(j)) == j);
1724         CHECK(float_json::from_msgpack(float_json::to_msgpack(j)) == j);
1725         CHECK(float_json::from_ubjson(float_json::to_ubjson(j)) == j);
1726 
1727         float_json j2 = {1000.0, 2000.0, 3000.0};
1728         CHECK(float_json::from_ubjson(float_json::to_ubjson(j2, true, true)) == j2);
1729     }
1730 
1731     SECTION("issue #1045 - Using STL algorithms with JSON containers with expected results?")
1732     {
1733         json diffs = nlohmann::json::array();
1734         json m1{{"key1", 42}};
1735         json m2{{"key2", 42}};
1736         auto p1 = m1.items();
1737         auto p2 = m2.items();
1738 
1739         using it_type = decltype(p1.begin());
1740 
1741         std::set_difference(
1742             p1.begin(), p1.end(),
1743             p2.begin(), p2.end(),
1744             std::inserter(diffs, diffs.end()), [&](const it_type & e1, const it_type & e2) -> bool
1745         {
1746             using comper_pair = std::pair<std::string, decltype(e1.value())>; // Trying to avoid unneeded copy
1747             return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
1748         });
1749 
1750         CHECK(diffs.size() == 1); // Note the change here, was 2
1751     }
1752 
1753 #ifdef JSON_HAS_CPP_17
1754     SECTION("issue #1292 - Serializing std::variant causes stack overflow")
1755     {
1756         static_assert(
1757             not std::is_constructible<json, std::variant<int, float>>::value, "");
1758     }
1759 #endif
1760 
1761     SECTION("issue #1299 - compile error in from_json converting to container "
1762             "with std::pair")
1763     {
1764         json j =
1765         {
1766             {"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
1767             {"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
1768             {"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
1769         };
1770 
1771         std::map<std::string, Data> expected
1772         {
1773             {"1", {"testa_1", "testb_1"}},
1774             {"2", {"testa_2", "testb_2"}},
1775             {"3", {"testa_3", "testb_3"}},
1776         };
1777         const auto data = j.get<decltype(expected)>();
1778         CHECK(expected == data);
1779     }
1780 
1781     SECTION("issue #1445 - buffer overflow in dumping invalid utf-8 strings")
1782     {
1783         SECTION("a bunch of -1, ensure_ascii=true")
1784         {
1785             const auto length = 300;
1786 
1787             json dump_test;
1788             dump_test["1"] = std::string(length, -1);
1789 
1790             std::string expected = "{\"1\":\"";
1791             for (int i = 0; i < length; ++i)
1792             {
1793                 expected += "\\ufffd";
1794             }
1795             expected += "\"}";
1796 
1797             auto s = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
1798             CHECK(s == expected);
1799         }
1800         SECTION("a bunch of -2, ensure_ascii=false")
1801         {
1802             const auto length = 500;
1803 
1804             json dump_test;
1805             dump_test["1"] = std::string(length, -2);
1806 
1807             std::string expected = "{\"1\":\"";
1808             for (int i = 0; i < length; ++i)
1809             {
1810                 expected += "\xEF\xBF\xBD";
1811             }
1812             expected += "\"}";
1813 
1814             auto s = dump_test.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);
1815             CHECK(s == expected);
1816         }
1817         SECTION("test case in issue #1445")
1818         {
1819             nlohmann::json dump_test;
1820             const int data[] =
1821             {
1822                 109,  108,  103,  125,  -122, -53,  115,
1823                 18,   3,    0,    102,  19,   1,    15,
1824                 -110, 13,   -3,   -1,   -81,  32,   2,
1825                 0,    0,    0,    0,    0,    0,    0,
1826                 8,    0,    0,    0,    0,    0,    0,
1827                 0,    0,    0,    0,    0,    -80,  2,
1828                 0,    0,    96,   -118, 46,   -116, 46,
1829                 109,  -84,  -87,  108,  14,   109,  -24,
1830                 -83,  13,   -18,  -51,  -83,  -52,  -115,
1831                 14,   6,    32,   0,    0,    0,    0,
1832                 0,    0,    0,    0,    0,    0,    0,
1833                 64,   3,    0,    0,    0,    35,   -74,
1834                 -73,  55,   57,   -128, 0,    0,    0,
1835                 0,    0,    0,    0,    0,    0,    0,
1836                 0,    0,    33,   0,    0,    0,    -96,
1837                 -54,  -28,  -26
1838             };
1839             std::string s;
1840             for (unsigned i = 0; i < sizeof(data) / sizeof(int); i++)
1841             {
1842                 s += static_cast<char>(data[i]);
1843             }
1844             dump_test["1"] = s;
1845             dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
1846         }
1847     }
1848 
1849     SECTION("issue #1447 - Integer Overflow (OSS-Fuzz 12506)")
1850     {
1851         json j = json::parse("[-9223372036854775808]");
1852         CHECK(j.dump() == "[-9223372036854775808]");
1853     }
1854 
1855     SECTION("issue #1708 - minimum value of int64_t can be outputted")
1856     {
1857         constexpr auto smallest = (std::numeric_limits<int64_t>::min)();
1858         json j = smallest;
1859         CHECK(j.dump() == std::to_string(smallest));
1860     }
1861 
1862     SECTION("issue #1727 - Contains with non-const lvalue json_pointer picks the wrong overload")
1863     {
1864         json j = {{"root", {{"settings", {{"logging", true}}}}}};
1865 
1866         auto jptr1 = "/root/settings/logging"_json_pointer;
1867         auto jptr2 = json::json_pointer{"/root/settings/logging"};
1868 
1869         CHECK(j.contains(jptr1));
1870         CHECK(j.contains(jptr2));
1871     }
1872 
1873     SECTION("issue #1647 - compile error when deserializing enum if both non-default from_json and non-member operator== exists for other type")
1874     {
1875         {
1876             json j;
1877             NonDefaultFromJsonStruct x = j;
1878             NonDefaultFromJsonStruct y;
1879             CHECK(x == y);
1880         }
1881 
1882         auto val = nlohmann::json("one").get<for_1647>();
1883         CHECK(val == for_1647::one);
1884         json j = val;
1885     }
1886 
1887     SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible")
1888     {
1889         static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "");
1890         static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "");
1891         static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "");
1892     }
1893     SECTION("issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible")
1894     {
1895         static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "");
1896         static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "");
1897         static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "");
1898     }
1899 }
1900 
1901 #if not defined(JSON_NOEXCEPTION)
1902 TEST_CASE("regression tests, exceptions dependent")
1903 {
1904     SECTION("issue #1340 - eof not set on exhausted input stream")
1905     {
1906         std::stringstream s("{}{}");
1907         json j;
1908         s >> j;
1909         s >> j;
1910         CHECK_THROWS_AS(s >> j, json::parse_error const&);
1911         CHECK(s.eof());
1912     }
1913 }
1914 #endif
1915 
1916 /////////////////////////////////////////////////////////////////////
1917 // for #1642
1918 /////////////////////////////////////////////////////////////////////
1919 template <typename T> class array {};
1920 template <typename T> class object {};
1921 template <typename T> class string {};
1922 template <typename T> class number_integer {};
1923 template <typename T> class number_unsigned {};
1924 template <typename T> class number_float {};
1925