unit-regression1.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++ (supporting code)
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #include "doctest_compatibility.h"
  9. // for some reason including this after the json header leads to linker errors with VS 2017...
  10. #include <locale>
  11. #define JSON_TESTS_PRIVATE
  12. #include <nlohmann/json.hpp>
  13. using nlohmann::json;
  14. #ifdef JSON_TEST_NO_GLOBAL_UDLS
  15. using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
  16. #endif
  17. #include <fstream>
  18. #include <sstream>
  19. #include <list>
  20. #include <limits>
  21. #include <cstdio>
  22. #include "make_test_data_available.hpp"
  23. #ifdef JSON_HAS_CPP_17
  24. #include <variant>
  25. #endif
  26. #include "fifo_map.hpp"
  27. /////////////////////////////////////////////////////////////////////
  28. // for #972
  29. /////////////////////////////////////////////////////////////////////
  30. template<class K, class V, class dummy_compare, class A>
  31. using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
  32. using my_json = nlohmann::basic_json<my_workaround_fifo_map>;
  33. /////////////////////////////////////////////////////////////////////
  34. // for #977
  35. /////////////////////////////////////////////////////////////////////
  36. namespace ns
  37. {
  38. struct foo
  39. {
  40. int x;
  41. };
  42. template <typename, typename SFINAE = void>
  43. struct foo_serializer;
  44. template<typename T>
  45. struct foo_serializer<T, typename std::enable_if<std::is_same<foo, T>::value>::type>
  46. {
  47. template <typename BasicJsonType>
  48. static void to_json(BasicJsonType& j, const T& value)
  49. {
  50. j = BasicJsonType{{"x", value.x}};
  51. }
  52. template <typename BasicJsonType>
  53. static void from_json(const BasicJsonType& j, T& value) // !!!
  54. {
  55. nlohmann::from_json(j.at("x"), value.x);
  56. }
  57. };
  58. template<typename T>
  59. struct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::value >::type >
  60. {
  61. template <typename BasicJsonType>
  62. static void to_json(BasicJsonType& j, const T& value) noexcept // NOLINT(bugprone-exception-escape)
  63. {
  64. ::nlohmann::to_json(j, value);
  65. }
  66. template <typename BasicJsonType>
  67. static void from_json(const BasicJsonType& j, T& value) //!!!
  68. {
  69. ::nlohmann::from_json(j, value);
  70. }
  71. };
  72. } // namespace ns
  73. using foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
  74. std::uint64_t, double, std::allocator, ns::foo_serializer, std::vector<std::uint8_t>>;
  75. /////////////////////////////////////////////////////////////////////
  76. // for #805
  77. /////////////////////////////////////////////////////////////////////
  78. namespace
  79. {
  80. struct nocopy // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
  81. {
  82. nocopy() = default;
  83. nocopy(const nocopy&) = delete;
  84. nocopy(nocopy&&) = delete;
  85. nocopy& operator=(const nocopy&) = delete;
  86. nocopy& operator=(nocopy&&) = delete;
  87. int val = 0;
  88. friend void to_json(json& j, const nocopy& n)
  89. {
  90. j = {{"val", n.val}};
  91. }
  92. };
  93. } // namespace
  94. TEST_CASE("regression tests 1")
  95. {
  96. SECTION("issue #60 - Double quotation mark is not parsed correctly")
  97. {
  98. SECTION("escape_doublequote")
  99. {
  100. const auto* s = R"(["\"foo\""])";
  101. json j = json::parse(s);
  102. auto expected = R"(["\"foo\""])"_json;
  103. CHECK(j == expected);
  104. }
  105. }
  106. SECTION("issue #70 - Handle infinity and NaN cases")
  107. {
  108. // previously, NAN/INFINITY created a null value; now, the values are
  109. // properly stored, but are dumped as "null"
  110. SECTION("NAN value")
  111. {
  112. CHECK(json(NAN).dump() == "null");
  113. CHECK(json(json::number_float_t(NAN)).dump() == "null");
  114. }
  115. SECTION("infinity")
  116. {
  117. CHECK(json(INFINITY).dump() == "null");
  118. CHECK(json(json::number_float_t(INFINITY)).dump() == "null");
  119. }
  120. // With 3.0.0, the semantics of this changed: NAN and infinity are
  121. // stored properly inside the JSON value (no exception or conversion
  122. // to null), but are serialized as null.
  123. SECTION("NAN value")
  124. {
  125. json const j1 = NAN;
  126. CHECK(j1.is_number_float());
  127. json::number_float_t const f1{j1};
  128. CHECK(std::isnan(f1));
  129. json const j2 = static_cast<json::number_float_t>(NAN);
  130. CHECK(j2.is_number_float());
  131. json::number_float_t const f2{j2};
  132. CHECK(std::isnan(f2));
  133. }
  134. SECTION("infinity")
  135. {
  136. json const j1 = INFINITY;
  137. CHECK(j1.is_number_float());
  138. json::number_float_t const f1{j1};
  139. CHECK(!std::isfinite(f1));
  140. json const j2 = static_cast<json::number_float_t>(INFINITY);
  141. CHECK(j2.is_number_float());
  142. json::number_float_t const f2{j2};
  143. CHECK(!std::isfinite(f2));
  144. }
  145. }
  146. SECTION("pull request #71 - handle enum type")
  147. {
  148. enum { t = 0, u = 102};
  149. json j = json::array();
  150. j.push_back(t);
  151. // maybe this is not the place to test this?
  152. json j2 = u;
  153. auto anon_enum_value = j2.get<decltype(u)>();
  154. CHECK(u == anon_enum_value);
  155. // check if the actual value was stored
  156. CHECK(j2 == 102);
  157. static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "types must be the same");
  158. j.push_back(json::object(
  159. {
  160. {"game_type", t}
  161. }));
  162. }
  163. SECTION("issue #76 - dump() / parse() not idempotent")
  164. {
  165. // create JSON object
  166. json fields;
  167. fields["one"] = std::string("one");
  168. fields["two"] = std::string("two three");
  169. fields["three"] = std::string("three \"four\"");
  170. // create another JSON object by deserializing the serialization
  171. std::string const payload = fields.dump();
  172. json parsed_fields = json::parse(payload);
  173. // check individual fields to match both objects
  174. CHECK(parsed_fields["one"] == fields["one"]);
  175. CHECK(parsed_fields["two"] == fields["two"]);
  176. CHECK(parsed_fields["three"] == fields["three"]);
  177. // check individual fields to match original input
  178. CHECK(parsed_fields["one"] == std::string("one"));
  179. CHECK(parsed_fields["two"] == std::string("two three"));
  180. CHECK(parsed_fields["three"] == std::string("three \"four\""));
  181. // check equality of the objects
  182. CHECK(parsed_fields == fields);
  183. // check equality of the serialized objects
  184. CHECK(fields.dump() == parsed_fields.dump());
  185. // check everything in one line
  186. CHECK(fields == json::parse(fields.dump()));
  187. }
  188. SECTION("issue #82 - lexer::get_number return NAN")
  189. {
  190. const auto* const content = R"(
  191. {
  192. "Test":"Test1",
  193. "Number":100,
  194. "Foo":42.42
  195. })";
  196. std::stringstream ss;
  197. ss << content;
  198. json j;
  199. ss >> j;
  200. auto test = j["Test"].get<std::string>();
  201. CHECK(test == "Test1");
  202. int number{j["Number"]};
  203. CHECK(number == 100);
  204. float foo{j["Foo"]};
  205. CHECK(static_cast<double>(foo) == Approx(42.42));
  206. }
  207. SECTION("issue #89 - nonstandard integer type")
  208. {
  209. // create JSON class with nonstandard integer number type
  210. using custom_json =
  211. nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
  212. custom_json j;
  213. j["int_1"] = 1;
  214. CHECK(j["int_1"] == 1);
  215. // tests for correct handling of non-standard integers that overflow the type selected by the user
  216. // unsigned integer object creation - expected to wrap and still be stored as an integer
  217. j = 4294967296U; // 2^32
  218. CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_unsigned));
  219. CHECK(j.get<uint32_t>() == 0); // Wrap
  220. // unsigned integer parsing - expected to overflow and be stored as a float
  221. j = custom_json::parse("4294967296"); // 2^32
  222. CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
  223. CHECK(j.get<float>() == 4294967296.0f);
  224. // integer object creation - expected to wrap and still be stored as an integer
  225. j = -2147483649LL; // -2^31-1
  226. CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_integer));
  227. CHECK(j.get<int32_t>() == 2147483647); // Wrap
  228. // integer parsing - expected to overflow and be stored as a float with rounding
  229. j = custom_json::parse("-2147483649"); // -2^31
  230. CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
  231. CHECK(j.get<float>() == -2147483650.0f);
  232. }
  233. SECTION("issue #93 reverse_iterator operator inheritance problem")
  234. {
  235. {
  236. json a = {1, 2, 3};
  237. json::reverse_iterator rit = a.rbegin();
  238. ++rit;
  239. CHECK(*rit == json(2));
  240. CHECK(rit.value() == json(2));
  241. }
  242. {
  243. json a = {1, 2, 3};
  244. json::reverse_iterator const rit = ++a.rbegin();
  245. CHECK(*rit == json(2));
  246. CHECK(rit.value() == json(2));
  247. }
  248. {
  249. json a = {1, 2, 3};
  250. json::reverse_iterator rit = a.rbegin();
  251. ++rit;
  252. json b = {0, 0, 0};
  253. std::transform(rit, a.rend(), b.rbegin(), [](json el)
  254. {
  255. return el;
  256. });
  257. CHECK(b == json({0, 1, 2}));
  258. }
  259. {
  260. json a = {1, 2, 3};
  261. json b = {0, 0, 0};
  262. std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)
  263. {
  264. return el;
  265. });
  266. CHECK(b == json({0, 1, 2}));
  267. }
  268. }
  269. SECTION("issue #100 - failed to iterator json object with reverse_iterator")
  270. {
  271. json config =
  272. {
  273. { "111", 111 },
  274. { "112", 112 },
  275. { "113", 113 }
  276. };
  277. std::stringstream ss;
  278. for (auto it = config.begin(); it != config.end(); ++it)
  279. {
  280. ss << it.key() << ": " << it.value() << '\n';
  281. }
  282. for (auto it = config.rbegin(); it != config.rend(); ++it)
  283. {
  284. ss << it.key() << ": " << it.value() << '\n';
  285. }
  286. CHECK(ss.str() == "111: 111\n112: 112\n113: 113\n113: 113\n112: 112\n111: 111\n");
  287. }
  288. SECTION("issue #101 - binary string causes numbers to be dumped as hex")
  289. {
  290. int64_t const number = 10;
  291. std::string const bytes{"\x00" "asdf\n", 6};
  292. json j;
  293. j["int64"] = number;
  294. j["binary string"] = bytes;
  295. // make sure the number is really printed as decimal "10" and not as
  296. // hexadecimal "a"
  297. CHECK(j.dump() == "{\"binary string\":\"\\u0000asdf\\n\",\"int64\":10}");
  298. }
  299. SECTION("issue #111 - subsequent unicode chars")
  300. {
  301. std::string const bytes{0x7, 0x7};
  302. json j;
  303. j["string"] = bytes;
  304. CHECK(j["string"] == "\u0007\u0007");
  305. }
  306. #if JSON_USE_IMPLICIT_CONVERSIONS
  307. SECTION("issue #144 - implicit assignment to std::string fails")
  308. {
  309. json o = {{"name", "value"}};
  310. std::string s1 = o["name"];
  311. CHECK(s1 == "value");
  312. std::string s2;
  313. s2 = o["name"];
  314. CHECK(s2 == "value");
  315. // improve coverage
  316. o["int"] = 1;
  317. #if JSON_DIAGNOSTICS
  318. CHECK_THROWS_WITH_AS(s2 = o["int"], "[json.exception.type_error.302] (/int) type must be string, but is number", json::type_error);
  319. #else
  320. CHECK_THROWS_WITH_AS(s2 = o["int"], "[json.exception.type_error.302] type must be string, but is number", json::type_error);
  321. #endif
  322. }
  323. #endif
  324. SECTION("issue #146 - character following a surrogate pair is skipped")
  325. {
  326. CHECK(json::parse("\"\\ud80c\\udc60abc\"").get<json::string_t>() == "\xf0\x93\x81\xa0\x61\x62\x63");
  327. }
  328. SECTION("issue #171 - Cannot index by key of type static constexpr const char*")
  329. {
  330. json j;
  331. // Non-const access with key as "char []"
  332. char array_key[] = "Key1"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  333. CHECK_NOTHROW(j[array_key] = 1);
  334. CHECK(j[array_key] == json(1));
  335. // Non-const access with key as "const char[]"
  336. const char const_array_key[] = "Key2"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  337. CHECK_NOTHROW(j[const_array_key] = 2);
  338. CHECK(j[const_array_key] == json(2));
  339. // Non-const access with key as "char *"
  340. char _ptr_key[] = "Key3"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  341. char* ptr_key = &_ptr_key[0]; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
  342. CHECK_NOTHROW(j[ptr_key] = 3);
  343. CHECK(j[ptr_key] == json(3));
  344. // Non-const access with key as "const char *"
  345. const char* const_ptr_key = "Key4";
  346. CHECK_NOTHROW(j[const_ptr_key] = 4);
  347. CHECK(j[const_ptr_key] == json(4));
  348. // Non-const access with key as "static constexpr const char *"
  349. static constexpr const char* constexpr_ptr_key = "Key5";
  350. CHECK_NOTHROW(j[constexpr_ptr_key] = 5);
  351. CHECK(j[constexpr_ptr_key] == json(5));
  352. const json j_const = j;
  353. // Const access with key as "char []"
  354. CHECK(j_const[array_key] == json(1));
  355. // Const access with key as "const char[]"
  356. CHECK(j_const[const_array_key] == json(2));
  357. // Const access with key as "char *"
  358. CHECK(j_const[ptr_key] == json(3));
  359. // Const access with key as "const char *"
  360. CHECK(j_const[const_ptr_key] == json(4));
  361. // Const access with key as "static constexpr const char *"
  362. CHECK(j_const[constexpr_ptr_key] == json(5));
  363. }
  364. SECTION("issue #186 miloyip/nativejson-benchmark: floating-point parsing")
  365. {
  366. json j;
  367. j = json::parse("-0.0");
  368. CHECK(j.get<double>() == -0.0);
  369. j = json::parse("2.22507385850720113605740979670913197593481954635164564e-308");
  370. CHECK(j.get<double>() == 2.2250738585072009e-308);
  371. j = json::parse("0.999999999999999944488848768742172978818416595458984374");
  372. CHECK(j.get<double>() == 0.99999999999999989);
  373. j = json::parse("1.00000000000000011102230246251565404236316680908203126");
  374. CHECK(j.get<double>() == 1.00000000000000022);
  375. j = json::parse("7205759403792793199999e-5");
  376. CHECK(j.get<double>() == 72057594037927928.0);
  377. j = json::parse("922337203685477529599999e-5");
  378. CHECK(j.get<double>() == 9223372036854774784.0);
  379. j = json::parse("1014120480182583464902367222169599999e-5");
  380. CHECK(j.get<double>() == 10141204801825834086073718800384.0);
  381. j = json::parse("5708990770823839207320493820740630171355185151999e-3");
  382. CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);
  383. // create JSON class with nonstandard float number type
  384. // float
  385. nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> const j_float =
  386. 1.23e25f;
  387. CHECK(j_float.get<float>() == 1.23e25f);
  388. // double
  389. nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> const j_double =
  390. 1.23e35;
  391. CHECK(j_double.get<double>() == 1.23e35);
  392. // long double
  393. nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>
  394. const j_long_double = 1.23e45L;
  395. CHECK(j_long_double.get<long double>() == 1.23e45L);
  396. }
  397. SECTION("issue #228 - double values are serialized with commas as decimal points")
  398. {
  399. json const j1a = 2312.42;
  400. json const j1b = json::parse("2312.42");
  401. json const j2a = 2342e-2;
  402. //issue #230
  403. //json j2b = json::parse("2342e-2");
  404. json const j3a = 10E3;
  405. json const j3b = json::parse("10E3");
  406. json const j3c = json::parse("10e3");
  407. // class to create a locale that would use a comma for decimals
  408. class CommaDecimalSeparator : public std::numpunct<char>
  409. {
  410. protected:
  411. char do_decimal_point() const override
  412. {
  413. return ',';
  414. }
  415. char do_thousands_sep() const override
  416. {
  417. return '.';
  418. }
  419. std::string do_grouping() const override
  420. {
  421. return "\03";
  422. }
  423. };
  424. // change locale to mess with decimal points
  425. auto orig_locale = std::locale::global(std::locale(std::locale(), new CommaDecimalSeparator));
  426. CHECK(j1a.dump() == "2312.42");
  427. CHECK(j1b.dump() == "2312.42");
  428. // check if locale is properly reset
  429. std::stringstream ss;
  430. ss.imbue(std::locale(std::locale(), new CommaDecimalSeparator));
  431. ss << 4712.11;
  432. CHECK(ss.str() == "4.712,11");
  433. ss << j1a;
  434. CHECK(ss.str() == "4.712,112312.42");
  435. ss << 47.11;
  436. CHECK(ss.str() == "4.712,112312.4247,11");
  437. CHECK(j2a.dump() == "23.42");
  438. //issue #230
  439. //CHECK(j2b.dump() == "23.42");
  440. CHECK(j3a.dump() == "10000.0");
  441. CHECK(j3b.dump() == "10000.0");
  442. CHECK(j3c.dump() == "10000.0");
  443. //CHECK(j3b.dump() == "1E04"); // roundtrip error
  444. //CHECK(j3c.dump() == "1e04"); // roundtrip error
  445. std::locale::global(orig_locale);
  446. }
  447. SECTION("issue #378 - locale-independent num-to-str")
  448. {
  449. static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
  450. // verify that dumped correctly with '.' and no grouping
  451. const json j1 = 12345.67;
  452. CHECK(json(12345.67).dump() == "12345.67");
  453. static_cast<void>(setlocale(LC_NUMERIC, "C"));
  454. }
  455. SECTION("issue #379 - locale-independent str-to-num")
  456. {
  457. static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
  458. // verify that parsed correctly despite using strtod internally
  459. CHECK(json::parse("3.14").get<double>() == 3.14);
  460. // check a different code path
  461. CHECK(json::parse("1.000000000000000000000000000000000000000000000000000000000000000000000000").get<double>() == 1.0);
  462. }
  463. SECTION("issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator")
  464. {
  465. json source = {"a", "b", "c"};
  466. json expected = {"a", "b"};
  467. json dest;
  468. std::copy_n(std::make_move_iterator(source.begin()), 2, std::back_inserter(dest));
  469. CHECK(dest == expected);
  470. }
  471. SECTION("issue #235 - ambiguous overload for 'push_back' and 'operator+='")
  472. {
  473. json data = {{"key", "value"}};
  474. data.push_back({"key2", "value2"});
  475. data += {"key3", "value3"};
  476. CHECK(data == json({{"key", "value"}, {"key2", "value2"}, {"key3", "value3"}}));
  477. }
  478. SECTION("issue #269 - diff generates incorrect patch when removing multiple array elements")
  479. {
  480. json const doc = R"( { "arr1": [1, 2, 3, 4] } )"_json;
  481. json expected = R"( { "arr1": [1, 2] } )"_json;
  482. // check roundtrip
  483. CHECK(doc.patch(json::diff(doc, expected)) == expected);
  484. }
  485. SECTION("issue #283 - value() does not work with _json_pointer types")
  486. {
  487. json j =
  488. {
  489. {"object", {{"key1", 1}, {"key2", 2}}},
  490. };
  491. int at_integer{j.at("/object/key2"_json_pointer)};
  492. int val_integer = j.value("/object/key2"_json_pointer, 0);
  493. CHECK(at_integer == val_integer);
  494. }
  495. SECTION("issue #304 - Unused variable warning")
  496. {
  497. // code triggered a "warning: unused variable" warning and is left
  498. // here to avoid the warning in the future
  499. json object;
  500. json const patch = json::array();
  501. object = object.patch(patch);
  502. }
  503. SECTION("issue #306 - Parsing fails without space at end of file")
  504. {
  505. for (const auto* filename :
  506. {
  507. TEST_DATA_DIRECTORY "/regression/broken_file.json",
  508. TEST_DATA_DIRECTORY "/regression/working_file.json"
  509. })
  510. {
  511. CAPTURE(filename)
  512. json j;
  513. std::ifstream f(filename);
  514. CHECK_NOTHROW(f >> j);
  515. }
  516. }
  517. SECTION("issue #310 - make json_benchmarks no longer working in 2.0.4")
  518. {
  519. for (const auto* filename :
  520. {
  521. TEST_DATA_DIRECTORY "/regression/floats.json",
  522. TEST_DATA_DIRECTORY "/regression/signed_ints.json",
  523. TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
  524. TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"
  525. })
  526. {
  527. CAPTURE(filename)
  528. json j;
  529. std::ifstream f(filename);
  530. CHECK_NOTHROW(f >> j);
  531. }
  532. }
  533. SECTION("issue #323 - add nested object capabilities to pointers")
  534. {
  535. json j;
  536. j["/this/that/2"_json_pointer] = 27;
  537. CHECK(j == json({{"this", {{"that", {nullptr, nullptr, 27}}}}}));
  538. }
  539. SECTION("issue #329 - serialized value not always can be parsed")
  540. {
  541. json _;
  542. CHECK_THROWS_WITH_AS(_ = json::parse("22e2222"), "[json.exception.out_of_range.406] number overflow parsing '22e2222'", json::out_of_range&);
  543. }
  544. SECTION("issue #360 - Loss of precision when serializing <double>")
  545. {
  546. auto check_roundtrip = [](double number)
  547. {
  548. CAPTURE(number)
  549. json j = number;
  550. CHECK(j.is_number_float());
  551. std::stringstream ss;
  552. ss << j;
  553. CHECK_NOTHROW(ss >> j);
  554. CHECK(j.is_number_float());
  555. CHECK(j.get<json::number_float_t>() == number);
  556. };
  557. check_roundtrip(100000000000.1236);
  558. check_roundtrip((std::numeric_limits<json::number_float_t>::max)());
  559. // Some more numbers which fail to roundtrip when serialized with digits10 significand digits (instead of max_digits10)
  560. check_roundtrip(1.541888611948064e-17);
  561. check_roundtrip(5.418771028591015e-16);
  562. check_roundtrip(9.398685592608595e-15);
  563. check_roundtrip(8.826843952762347e-14);
  564. check_roundtrip(8.143291313475335e-13);
  565. check_roundtrip(4.851328172762508e-12);
  566. check_roundtrip(6.677850998084358e-11);
  567. check_roundtrip(3.995398518174525e-10);
  568. check_roundtrip(1.960452605645124e-9);
  569. check_roundtrip(3.551812586302883e-8);
  570. check_roundtrip(2.947988411689261e-7);
  571. check_roundtrip(8.210166748056192e-6);
  572. check_roundtrip(6.104889704266753e-5);
  573. check_roundtrip(0.0008629954631330876);
  574. check_roundtrip(0.004936993881051611);
  575. check_roundtrip(0.08309725102608073);
  576. check_roundtrip(0.5210494268499783);
  577. check_roundtrip(6.382927930939767);
  578. check_roundtrip(59.94947245358671);
  579. check_roundtrip(361.0838651266122);
  580. check_roundtrip(4678.354596181877);
  581. check_roundtrip(61412.17658956043);
  582. check_roundtrip(725696.0799057782);
  583. check_roundtrip(2811732.583399828);
  584. check_roundtrip(30178351.07533605);
  585. check_roundtrip(689684880.3235844);
  586. check_roundtrip(5714887673.555147);
  587. check_roundtrip(84652038821.18808);
  588. check_roundtrip(156510583431.7721);
  589. check_roundtrip(5938450569021.732);
  590. check_roundtrip(83623297654460.33);
  591. check_roundtrip(701466573254773.6);
  592. check_roundtrip(1369013370304513);
  593. check_roundtrip(96963648023094720); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
  594. check_roundtrip(3.478237409280108e+17);
  595. }
  596. SECTION("issue #366 - json::parse on failed stream gets stuck")
  597. {
  598. std::ifstream f("file_not_found.json");
  599. json _;
  600. CHECK_THROWS_WITH_AS(_ = 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", json::parse_error&);
  601. }
  602. SECTION("issue #367 - calling stream at EOF")
  603. {
  604. std::stringstream ss;
  605. json j;
  606. ss << "123";
  607. CHECK_NOTHROW(ss >> j);
  608. // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
  609. // ss is not at EOF; this yielded an error before the fix
  610. // (threw basic_string::append). No, it should just throw
  611. // a parse error because of the EOF.
  612. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  613. }
  614. SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
  615. {
  616. SECTION("(empty)")
  617. {
  618. std::stringstream ss;
  619. json j;
  620. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  621. }
  622. SECTION("(whitespace)")
  623. {
  624. std::stringstream ss;
  625. ss << " ";
  626. json j;
  627. CHECK_THROWS_WITH_AS(ss >> j,
  628. "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
  629. }
  630. SECTION("one value")
  631. {
  632. std::stringstream ss;
  633. ss << "111";
  634. json j;
  635. CHECK_NOTHROW(ss >> j);
  636. CHECK(j == 111);
  637. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  638. }
  639. SECTION("one value + whitespace")
  640. {
  641. std::stringstream ss;
  642. ss << "222 \t\n";
  643. json j;
  644. CHECK_NOTHROW(ss >> j);
  645. CHECK(j == 222);
  646. CHECK_THROWS_WITH_AS(ss >> j,
  647. "[json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
  648. }
  649. SECTION("whitespace + one value")
  650. {
  651. std::stringstream ss;
  652. ss << "\n\t 333";
  653. json j;
  654. CHECK_NOTHROW(ss >> j);
  655. CHECK(j == 333);
  656. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  657. }
  658. SECTION("three values")
  659. {
  660. std::stringstream ss;
  661. ss << " 111 \n222\n \n 333";
  662. json j;
  663. CHECK_NOTHROW(ss >> j);
  664. CHECK(j == 111);
  665. CHECK_NOTHROW(ss >> j);
  666. CHECK(j == 222);
  667. CHECK_NOTHROW(ss >> j);
  668. CHECK(j == 333);
  669. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  670. }
  671. SECTION("literals without whitespace")
  672. {
  673. std::stringstream ss;
  674. ss << "truefalsenull\"\"";
  675. json j;
  676. CHECK_NOTHROW(ss >> j);
  677. CHECK(j == true);
  678. CHECK_NOTHROW(ss >> j);
  679. CHECK(j == false);
  680. CHECK_NOTHROW(ss >> j);
  681. CHECK(j == nullptr);
  682. CHECK_NOTHROW(ss >> j);
  683. CHECK(j == "");
  684. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  685. }
  686. SECTION("example from #529")
  687. {
  688. std::stringstream ss;
  689. ss << "{\n \"one\" : 1,\n \"two\" : 2\n}\n{\n \"three\" : 3\n}";
  690. json j;
  691. CHECK_NOTHROW(ss >> j);
  692. CHECK(j == json({{"one", 1}, {"two", 2}}));
  693. CHECK_NOTHROW(ss >> j);
  694. CHECK(j == json({{"three", 3}}));
  695. CHECK_THROWS_WITH_AS(ss >> j, "[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", json::parse_error&);
  696. }
  697. SECTION("second example from #529")
  698. {
  699. std::string const str = "{\n\"one\" : 1,\n\"two\" : 2\n}\n{\n\"three\" : 3\n}";
  700. {
  701. std::ofstream file("test.json");
  702. file << str;
  703. }
  704. std::ifstream stream("test.json", std::ifstream::in);
  705. json val;
  706. size_t i = 0;
  707. while (stream.peek() != EOF)
  708. {
  709. CAPTURE(i)
  710. CHECK_NOTHROW(stream >> val);
  711. CHECK(i < 2);
  712. if (i == 0)
  713. {
  714. CHECK(val == json({{"one", 1}, {"two", 2}}));
  715. }
  716. if (i == 1)
  717. {
  718. CHECK(val == json({{"three", 3}}));
  719. }
  720. ++i;
  721. }
  722. static_cast<void>(std::remove("test.json"));
  723. }
  724. }
  725. SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
  726. {
  727. // original test case
  728. json const j1 = json::parse("-9223372036854775808");
  729. CHECK(j1.is_number_integer());
  730. CHECK(j1.get<json::number_integer_t>() == (std::numeric_limits<std::int64_t>::min)());
  731. // edge case (+1; still an integer)
  732. json const j2 = json::parse("-9223372036854775807");
  733. CHECK(j2.is_number_integer());
  734. CHECK(j2.get<json::number_integer_t>() == (std::numeric_limits<std::int64_t>::min)() + 1);
  735. // edge case (-1; overflow -> floats)
  736. json const j3 = json::parse("-9223372036854775809");
  737. CHECK(j3.is_number_float());
  738. }
  739. SECTION("issue #380 - bug in overflow detection when parsing integers")
  740. {
  741. json const j = json::parse("166020696663385964490");
  742. CHECK(j.is_number_float());
  743. CHECK(j.get<json::number_float_t>() == 166020696663385964490.0);
  744. }
  745. SECTION("issue #405 - Heap-buffer-overflow (OSS-Fuzz issue 342)")
  746. {
  747. // original test case
  748. std::vector<uint8_t> const vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
  749. json _;
  750. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
  751. }
  752. SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
  753. {
  754. json _;
  755. // original test case: incomplete float64
  756. std::vector<uint8_t> const vec1 {0xcb, 0x8f, 0x0a};
  757. CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
  758. // related test case: incomplete float32
  759. std::vector<uint8_t> const vec2 {0xca, 0x8f, 0x0a};
  760. CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
  761. // related test case: incomplete Half-Precision Float (CBOR)
  762. std::vector<uint8_t> const vec3 {0xf9, 0x8f};
  763. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
  764. // related test case: incomplete Single-Precision Float (CBOR)
  765. std::vector<uint8_t> const vec4 {0xfa, 0x8f, 0x0a};
  766. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec4), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
  767. // related test case: incomplete Double-Precision Float (CBOR)
  768. std::vector<uint8_t> const vec5 {0xfb, 0x8f, 0x0a};
  769. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec5), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
  770. }
  771. SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
  772. {
  773. json _;
  774. // original test case
  775. std::vector<uint8_t> const vec1 {0x87};
  776. CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
  777. // more test cases for MessagePack
  778. for (auto b :
  779. {
  780. 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, // fixmap
  781. 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // fixarray
  782. 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // fixstr
  783. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
  784. })
  785. {
  786. std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
  787. CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);
  788. }
  789. // more test cases for CBOR
  790. for (auto b :
  791. {
  792. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  793. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // UTF-8 string
  794. 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  795. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, // array
  796. 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  797. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7 // map
  798. })
  799. {
  800. std::vector<uint8_t> const vec(1, static_cast<uint8_t>(b));
  801. CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);
  802. }
  803. // special case: empty input
  804. std::vector<uint8_t> const vec2;
  805. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
  806. CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
  807. }
  808. SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
  809. {
  810. json _;
  811. // original test case: empty UTF-8 string (indefinite length)
  812. std::vector<uint8_t> const vec1 {0x7f};
  813. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
  814. // related test case: empty array (indefinite length)
  815. std::vector<uint8_t> const vec2 {0x9f};
  816. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
  817. // related test case: empty map (indefinite length)
  818. std::vector<uint8_t> const vec3 {0xbf};
  819. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
  820. }
  821. SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
  822. {
  823. // original test case
  824. std::vector<uint8_t> const vec
  825. {
  826. 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
  827. 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
  828. 0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
  829. 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
  830. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  831. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  832. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  833. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  834. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  835. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  836. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,
  837. 0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  838. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  839. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  840. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  841. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
  842. 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
  843. };
  844. json _;
  845. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[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", json::parse_error&);
  846. // related test case: nonempty UTF-8 string (indefinite length)
  847. std::vector<uint8_t> const vec1 {0x7f, 0x61, 0x61};
  848. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
  849. // related test case: nonempty array (indefinite length)
  850. std::vector<uint8_t> const vec2 {0x9f, 0x01};
  851. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
  852. // related test case: nonempty map (indefinite length)
  853. std::vector<uint8_t> const vec3 {0xbf, 0x61, 0x61, 0x01};
  854. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
  855. }
  856. SECTION("issue #414 - compare with literal 0)")
  857. {
  858. #define CHECK_TYPE(v) \
  859. CHECK((json(v) == (v)));\
  860. CHECK(((v) == json(v)));\
  861. CHECK_FALSE((json(v) != (v)));\
  862. CHECK_FALSE(((v) != json(v)));
  863. CHECK_TYPE(nullptr)
  864. CHECK_TYPE(0)
  865. CHECK_TYPE(0u)
  866. CHECK_TYPE(0L)
  867. CHECK_TYPE(0.0)
  868. CHECK_TYPE("") // NOLINT(readability-container-size-empty)
  869. #undef CHECK_TYPE
  870. }
  871. SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
  872. {
  873. // original test case
  874. std::vector<uint8_t> const vec1
  875. {
  876. 0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
  877. 0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
  878. 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
  879. 0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
  880. 0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
  881. 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
  882. };
  883. json _;
  884. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[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", json::parse_error&);
  885. // related test case: double-precision
  886. std::vector<uint8_t> const vec2
  887. {
  888. 0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
  889. 0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
  890. 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
  891. 0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
  892. 0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
  893. 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
  894. };
  895. CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[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", json::parse_error&);
  896. }
  897. SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
  898. {
  899. std::vector<uint8_t> const vec = {'-', '0', '1', '2', '2', '7', '4'};
  900. json _;
  901. CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
  902. }
  903. SECTION("issue #454 - doubles are printed as integers")
  904. {
  905. 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;
  906. CHECK(j["double_value"].is_number_float());
  907. }
  908. #if JSON_USE_IMPLICIT_CONVERSIONS
  909. SECTION("issue #464 - VS2017 implicit to std::string conversion fix")
  910. {
  911. json v = "test";
  912. std::string test;
  913. test = v;
  914. CHECK(v == "test");
  915. }
  916. #endif
  917. SECTION("issue #465 - roundtrip error while parsing 1000000000000000010E5")
  918. {
  919. json const j1 = json::parse("1000000000000000010E5");
  920. std::string s1 = j1.dump();
  921. json const j2 = json::parse(s1);
  922. std::string s2 = j2.dump();
  923. CHECK(s1 == s2);
  924. }
  925. #if JSON_USE_IMPLICIT_CONVERSIONS
  926. SECTION("issue #473 - inconsistent behavior in conversion to array type")
  927. {
  928. json const j_array = {1, 2, 3, 4};
  929. json const j_number = 42;
  930. json const j_null = nullptr;
  931. SECTION("std::vector")
  932. {
  933. auto create = [](const json & j)
  934. {
  935. std::vector<int> const v = j;
  936. };
  937. CHECK_NOTHROW(create(j_array));
  938. CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  939. CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  940. }
  941. SECTION("std::list")
  942. {
  943. auto create = [](const json & j)
  944. {
  945. std::list<int> const v = j;
  946. };
  947. CHECK_NOTHROW(create(j_array));
  948. CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  949. CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  950. }
  951. SECTION("std::forward_list")
  952. {
  953. auto create = [](const json & j)
  954. {
  955. std::forward_list<int> const v = j;
  956. };
  957. CHECK_NOTHROW(create(j_array));
  958. CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  959. CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  960. }
  961. }
  962. #endif
  963. SECTION("issue #486 - json::value_t can't be a map's key type in VC++ 2015")
  964. {
  965. // the code below must compile with MSVC
  966. std::map<json::value_t, std::string> jsonTypes ;
  967. jsonTypes[json::value_t::array] = "array";
  968. }
  969. SECTION("issue #494 - conversion from vector<bool> to json fails to build")
  970. {
  971. std::vector<bool> const boolVector = {false, true, false, false};
  972. json j;
  973. j["bool_vector"] = boolVector;
  974. CHECK(j["bool_vector"].dump() == "[false,true,false,false]");
  975. }
  976. SECTION("issue #504 - assertion error (OSS-Fuzz 856)")
  977. {
  978. std::vector<uint8_t> const vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};
  979. json const j1 = json::from_cbor(vec1, false);
  980. // step 2: round trip
  981. std::vector<uint8_t> vec2 = json::to_cbor(j1);
  982. // parse serialization
  983. json const j2 = json::from_cbor(vec2);
  984. // NaN is dumped to "null"
  985. CHECK(j2.is_number_float());
  986. CHECK(std::isnan(j2.get<json::number_float_t>()));
  987. CHECK(j2.dump() == "null");
  988. // check if serializations match
  989. CHECK(json::to_cbor(j2) == vec2);
  990. }
  991. SECTION("issue #512 - use of overloaded operator '<=' is ambiguous")
  992. {
  993. json j;
  994. j["a"] = 5;
  995. // json op scalar
  996. CHECK(j["a"] == 5);
  997. CHECK(j["a"] != 4);
  998. CHECK(j["a"] <= 7);
  999. CHECK(j["a"] < 7);
  1000. CHECK(j["a"] >= 3);
  1001. CHECK(j["a"] > 3);
  1002. CHECK(!(j["a"] <= 4));
  1003. CHECK(!(j["a"] < 4));
  1004. CHECK(!(j["a"] >= 6));
  1005. CHECK(!(j["a"] > 6));
  1006. // scalar op json
  1007. CHECK(5 == j["a"]);
  1008. CHECK(4 != j["a"]);
  1009. CHECK(7 >= j["a"]);
  1010. CHECK(7 > j["a"]);
  1011. CHECK(3 <= j["a"]);
  1012. CHECK(3 < j["a"]);
  1013. CHECK(!(4 >= j["a"]));
  1014. CHECK(!(4 > j["a"]));
  1015. CHECK(!(6 <= j["a"]));
  1016. CHECK(!(6 < j["a"]));
  1017. }
  1018. SECTION("issue #575 - heap-buffer-overflow (OSS-Fuzz 1400)")
  1019. {
  1020. json _;
  1021. std::vector<uint8_t> const vec = {'"', '\\', '"', 'X', '"', '"'};
  1022. CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
  1023. }
  1024. #if JSON_USE_IMPLICIT_CONVERSIONS
  1025. SECTION("issue #600 - how does one convert a map in Json back to std::map?")
  1026. {
  1027. SECTION("example 1")
  1028. {
  1029. // create a map
  1030. std::map<std::string, int> m1 {{"key", 1}};
  1031. // create and print a JSON from the map
  1032. json const j = m1;
  1033. // get the map out of JSON
  1034. std::map<std::string, int> m2 = j;
  1035. // make sure the roundtrip succeeds
  1036. CHECK(m1 == m2);
  1037. }
  1038. SECTION("example 2")
  1039. {
  1040. // create a map
  1041. std::map<std::string, std::string> m1 {{"key", "val"}};
  1042. // create and print a JSON from the map
  1043. json const j = m1;
  1044. // get the map out of JSON
  1045. std::map<std::string, std::string> m2 = j;
  1046. // make sure the roundtrip succeeds
  1047. CHECK(m1 == m2);
  1048. }
  1049. }
  1050. #endif
  1051. SECTION("issue #602 - BOM not skipped when using json:parse(iterator)")
  1052. {
  1053. std::string i = "\xef\xbb\xbf{\n \"foo\": true\n}";
  1054. json _;
  1055. CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));
  1056. }
  1057. #if JSON_USE_IMPLICIT_CONVERSIONS
  1058. SECTION("issue #702 - conversion from valarray<double> to json fails to build")
  1059. {
  1060. SECTION("original example")
  1061. {
  1062. std::valarray<double> const v;
  1063. nlohmann::json j;
  1064. j["test"] = v;
  1065. }
  1066. SECTION("full example")
  1067. {
  1068. std::valarray<double> v = {1.2, 2.3, 3.4, 4.5};
  1069. json j = v;
  1070. std::valarray<double> vj = j;
  1071. CHECK(j == json(vj));
  1072. CHECK(v.size() == vj.size());
  1073. for (size_t i = 0; i < v.size(); ++i)
  1074. {
  1075. CHECK(v[i] == vj[i]);
  1076. CHECK(v[i] == j[i]);
  1077. }
  1078. CHECK_THROWS_WITH_AS(json().get<std::valarray<double>>(), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1079. }
  1080. }
  1081. #endif
  1082. SECTION("issue #367 - Behavior of operator>> should more closely resemble that of built-in overloads.")
  1083. {
  1084. SECTION("example 1")
  1085. {
  1086. std::istringstream i1_2_3( R"({"first": "one" }{"second": "two"}3)" );
  1087. json j1;
  1088. json j2;
  1089. json j3;
  1090. i1_2_3 >> j1;
  1091. i1_2_3 >> j2;
  1092. i1_2_3 >> j3;
  1093. auto m1 = j1.get<std::map<std::string, std::string>>();
  1094. auto m2 = j2.get<std::map<std::string, std::string>>();
  1095. int i3{j3};
  1096. CHECK( m1 == ( std::map<std::string, std::string> {{ "first", "one" }} ));
  1097. CHECK( m2 == ( std::map<std::string, std::string> {{ "second", "two" }} ));
  1098. CHECK( i3 == 3 );
  1099. }
  1100. }
  1101. SECTION("issue #714 - throw std::ios_base::failure exception when failbit set to true")
  1102. {
  1103. {
  1104. std::ifstream is;
  1105. is.exceptions(
  1106. is.exceptions()
  1107. | std::ios_base::failbit
  1108. | std::ios_base::badbit
  1109. ); // handle different exceptions as 'file not found', 'permission denied'
  1110. is.open(TEST_DATA_DIRECTORY "/regression/working_file.json");
  1111. json _;
  1112. CHECK_NOTHROW(_ = nlohmann::json::parse(is));
  1113. }
  1114. {
  1115. std::ifstream is;
  1116. is.exceptions(
  1117. is.exceptions()
  1118. | std::ios_base::failbit
  1119. | std::ios_base::badbit
  1120. ); // handle different exceptions as 'file not found', 'permission denied'
  1121. is.open(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json.cbor",
  1122. std::ios_base::in | std::ios_base::binary);
  1123. json _;
  1124. CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));
  1125. }
  1126. }
  1127. SECTION("issue #805 - copy constructor is used with std::initializer_list constructor.")
  1128. {
  1129. nocopy n;
  1130. json j;
  1131. j = {{"nocopy", n}};
  1132. CHECK(j["nocopy"]["val"] == 0);
  1133. }
  1134. SECTION("issue #838 - incorrect parse error with binary data in keys")
  1135. {
  1136. 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 }};
  1137. std::string const key1_str(reinterpret_cast<char*>(key1.data()));
  1138. json const j = key1_str;
  1139. CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
  1140. }
  1141. #if JSON_USE_IMPLICIT_CONVERSIONS
  1142. SECTION("issue #843 - converting to array not working")
  1143. {
  1144. json j;
  1145. std::array<int, 4> ar = {{1, 1, 1, 1}};
  1146. j = ar;
  1147. ar = j;
  1148. }
  1149. #endif
  1150. SECTION("issue #894 - invalid RFC6902 copy operation succeeds")
  1151. {
  1152. auto model = R"({
  1153. "one": {
  1154. "two": {
  1155. "three": "hello",
  1156. "four": 42
  1157. }
  1158. }
  1159. })"_json;
  1160. auto p1 = R"([{"op": "move",
  1161. "from": "/one/two/three",
  1162. "path": "/a/b/c"}])"_json;
  1163. CHECK_THROWS_WITH_AS(model.patch(p1),
  1164. "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
  1165. auto p2 = R"([{"op": "copy",
  1166. "from": "/one/two/three",
  1167. "path": "/a/b/c"}])"_json;
  1168. CHECK_THROWS_WITH_AS(model.patch(p2),
  1169. "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
  1170. }
  1171. SECTION("issue #961 - incorrect parsing of indefinite length CBOR strings")
  1172. {
  1173. std::vector<uint8_t> const v_cbor =
  1174. {
  1175. 0x7F,
  1176. 0x64,
  1177. 'a', 'b', 'c', 'd',
  1178. 0x63,
  1179. '1', '2', '3',
  1180. 0xFF
  1181. };
  1182. json j = json::from_cbor(v_cbor);
  1183. CHECK(j == "abcd123");
  1184. }
  1185. SECTION("issue #962 - Timeout (OSS-Fuzz 6034)")
  1186. {
  1187. json _;
  1188. std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
  1189. CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
  1190. //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
  1191. // "[json.exception.out_of_range.408] excessive array size: 8658170730974374167");
  1192. v_ubjson[0] = '{';
  1193. CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
  1194. //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
  1195. // "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
  1196. }
  1197. SECTION("issue #971 - Add a SAX parser - late bug")
  1198. {
  1199. // a JSON text
  1200. const auto* text = R"(
  1201. {
  1202. "Image": {
  1203. "Width": 800,
  1204. "Height": 600,
  1205. "Title": "View from 15th Floor",
  1206. "Thumbnail": {
  1207. "Url": "http://www.example.com/image/481989943",
  1208. "Height": 125,
  1209. "Width": 100
  1210. },
  1211. "Animated" : false,
  1212. "IDs": [116, 943, 234, 38793]
  1213. }
  1214. }
  1215. )";
  1216. // define parser callback
  1217. json::parser_callback_t const cb = [](int /*depth*/, json::parse_event_t event, json & parsed)
  1218. {
  1219. // skip object elements with key "Thumbnail"
  1220. return !(event == json::parse_event_t::key && parsed == json("Thumbnail"));
  1221. };
  1222. // parse (with callback) and serialize JSON
  1223. json j_filtered = json::parse(text, cb);
  1224. CHECK(j_filtered == R"({"Image":{"Animated":false,"Height":600,"IDs":[116,943,234,38793], "Title":"View from 15th Floor","Width":800}})"_json);
  1225. }
  1226. SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
  1227. {
  1228. my_json const foo = R"([1, 2, 3])"_json;
  1229. }
  1230. SECTION("issue #977 - Assigning between different json types")
  1231. {
  1232. foo_json lj = ns::foo{3};
  1233. ns::foo ff(lj);
  1234. CHECK(lj.is_object());
  1235. CHECK(lj.size() == 1);
  1236. CHECK(lj["x"] == 3);
  1237. CHECK(ff.x == 3);
  1238. nlohmann::json const nj = lj; // This line works as expected
  1239. }
  1240. }
  1241. #if !defined(JSON_NOEXCEPTION)
  1242. TEST_CASE("regression tests, exceptions dependent")
  1243. {
  1244. SECTION("issue #1340 - eof not set on exhausted input stream")
  1245. {
  1246. std::stringstream s("{}{}");
  1247. json j;
  1248. s >> j;
  1249. s >> j;
  1250. CHECK_THROWS_AS(s >> j, json::parse_error const&);
  1251. CHECK(s.eof());
  1252. }
  1253. }
  1254. #endif
  1255. /////////////////////////////////////////////////////////////////////
  1256. // for #1642
  1257. /////////////////////////////////////////////////////////////////////
  1258. // the code below fails with Clang on Windows, so we need to exclude it there
  1259. #if DOCTEST_CLANG && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))
  1260. #else
  1261. template <typename T> class array {};
  1262. template <typename T> class object {};
  1263. template <typename T> class string {};
  1264. template <typename T> class number_integer {};
  1265. template <typename T> class number_unsigned {};
  1266. template <typename T> class number_float {};
  1267. #endif