unit-bson.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  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. #include <nlohmann/json.hpp>
  10. using nlohmann::json;
  11. #include <fstream>
  12. #include <limits>
  13. #include <sstream>
  14. #include "make_test_data_available.hpp"
  15. #include "test_utils.hpp"
  16. TEST_CASE("BSON")
  17. {
  18. SECTION("individual values not supported")
  19. {
  20. SECTION("null")
  21. {
  22. json const j = nullptr;
  23. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null", json::type_error&);
  24. }
  25. SECTION("boolean")
  26. {
  27. SECTION("true")
  28. {
  29. json const j = true;
  30. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is boolean", json::type_error&);
  31. }
  32. SECTION("false")
  33. {
  34. json const j = false;
  35. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is boolean", json::type_error&);
  36. }
  37. }
  38. SECTION("number")
  39. {
  40. json const j = 42;
  41. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is number", json::type_error&);
  42. }
  43. SECTION("float")
  44. {
  45. json const j = 4.2;
  46. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is number", json::type_error&);
  47. }
  48. SECTION("string")
  49. {
  50. json const j = "not supported";
  51. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is string", json::type_error&);
  52. }
  53. SECTION("array")
  54. {
  55. json const j = std::vector<int> {1, 2, 3, 4, 5, 6, 7};
  56. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array", json::type_error&);
  57. }
  58. }
  59. SECTION("keys containing code-point U+0000 cannot be serialized to BSON")
  60. {
  61. json const j =
  62. {
  63. { std::string("en\0try", 6), true }
  64. };
  65. #if JSON_DIAGNOSTICS
  66. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.out_of_range.409] (/en) BSON key cannot contain code point U+0000 (at byte 2)", json::out_of_range&);
  67. #else
  68. CHECK_THROWS_WITH_AS(json::to_bson(j), "[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)", json::out_of_range&);
  69. #endif
  70. }
  71. SECTION("string length must be at least 1")
  72. {
  73. // from https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11175
  74. std::vector<std::uint8_t> const v =
  75. {
  76. 0x20, 0x20, 0x20, 0x20,
  77. 0x02,
  78. 0x00,
  79. 0x00, 0x00, 0x00, 0x80
  80. };
  81. json _;
  82. CHECK_THROWS_WITH_AS(_ = json::from_bson(v), "[json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648", json::parse_error&);
  83. }
  84. SECTION("objects")
  85. {
  86. SECTION("empty object")
  87. {
  88. json const j = json::object();
  89. std::vector<std::uint8_t> const expected =
  90. {
  91. 0x05, 0x00, 0x00, 0x00, // size (little endian)
  92. // no entries
  93. 0x00 // end marker
  94. };
  95. const auto result = json::to_bson(j);
  96. CHECK(result == expected);
  97. // roundtrip
  98. CHECK(json::from_bson(result) == j);
  99. CHECK(json::from_bson(result, true, false) == j);
  100. }
  101. SECTION("non-empty object with bool")
  102. {
  103. json const j =
  104. {
  105. { "entry", true }
  106. };
  107. std::vector<std::uint8_t> const expected =
  108. {
  109. 0x0D, 0x00, 0x00, 0x00, // size (little endian)
  110. 0x08, // entry: boolean
  111. 'e', 'n', 't', 'r', 'y', '\x00',
  112. 0x01, // value = true
  113. 0x00 // end marker
  114. };
  115. const auto result = json::to_bson(j);
  116. CHECK(result == expected);
  117. // roundtrip
  118. CHECK(json::from_bson(result) == j);
  119. CHECK(json::from_bson(result, true, false) == j);
  120. }
  121. SECTION("non-empty object with bool")
  122. {
  123. json const j =
  124. {
  125. { "entry", false }
  126. };
  127. std::vector<std::uint8_t> const expected =
  128. {
  129. 0x0D, 0x00, 0x00, 0x00, // size (little endian)
  130. 0x08, // entry: boolean
  131. 'e', 'n', 't', 'r', 'y', '\x00',
  132. 0x00, // value = false
  133. 0x00 // end marker
  134. };
  135. const auto result = json::to_bson(j);
  136. CHECK(result == expected);
  137. // roundtrip
  138. CHECK(json::from_bson(result) == j);
  139. CHECK(json::from_bson(result, true, false) == j);
  140. }
  141. SECTION("non-empty object with double")
  142. {
  143. json const j =
  144. {
  145. { "entry", 4.2 }
  146. };
  147. std::vector<std::uint8_t> const expected =
  148. {
  149. 0x14, 0x00, 0x00, 0x00, // size (little endian)
  150. 0x01, /// entry: double
  151. 'e', 'n', 't', 'r', 'y', '\x00',
  152. 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,
  153. 0x00 // end marker
  154. };
  155. const auto result = json::to_bson(j);
  156. CHECK(result == expected);
  157. // roundtrip
  158. CHECK(json::from_bson(result) == j);
  159. CHECK(json::from_bson(result, true, false) == j);
  160. }
  161. SECTION("non-empty object with string")
  162. {
  163. json const j =
  164. {
  165. { "entry", "bsonstr" }
  166. };
  167. std::vector<std::uint8_t> const expected =
  168. {
  169. 0x18, 0x00, 0x00, 0x00, // size (little endian)
  170. 0x02, /// entry: string (UTF-8)
  171. 'e', 'n', 't', 'r', 'y', '\x00',
  172. 0x08, 0x00, 0x00, 0x00, 'b', 's', 'o', 'n', 's', 't', 'r', '\x00',
  173. 0x00 // end marker
  174. };
  175. const auto result = json::to_bson(j);
  176. CHECK(result == expected);
  177. // roundtrip
  178. CHECK(json::from_bson(result) == j);
  179. CHECK(json::from_bson(result, true, false) == j);
  180. }
  181. SECTION("non-empty object with null member")
  182. {
  183. json const j =
  184. {
  185. { "entry", nullptr }
  186. };
  187. std::vector<std::uint8_t> const expected =
  188. {
  189. 0x0C, 0x00, 0x00, 0x00, // size (little endian)
  190. 0x0A, /// entry: null
  191. 'e', 'n', 't', 'r', 'y', '\x00',
  192. 0x00 // end marker
  193. };
  194. const auto result = json::to_bson(j);
  195. CHECK(result == expected);
  196. // roundtrip
  197. CHECK(json::from_bson(result) == j);
  198. CHECK(json::from_bson(result, true, false) == j);
  199. }
  200. SECTION("non-empty object with integer (32-bit) member")
  201. {
  202. json const j =
  203. {
  204. { "entry", std::int32_t{0x12345678} }
  205. };
  206. std::vector<std::uint8_t> const expected =
  207. {
  208. 0x10, 0x00, 0x00, 0x00, // size (little endian)
  209. 0x10, /// entry: int32
  210. 'e', 'n', 't', 'r', 'y', '\x00',
  211. 0x78, 0x56, 0x34, 0x12,
  212. 0x00 // end marker
  213. };
  214. const auto result = json::to_bson(j);
  215. CHECK(result == expected);
  216. // roundtrip
  217. CHECK(json::from_bson(result) == j);
  218. CHECK(json::from_bson(result, true, false) == j);
  219. }
  220. SECTION("non-empty object with integer (64-bit) member")
  221. {
  222. json const j =
  223. {
  224. { "entry", std::int64_t{0x1234567804030201} }
  225. };
  226. std::vector<std::uint8_t> const expected =
  227. {
  228. 0x14, 0x00, 0x00, 0x00, // size (little endian)
  229. 0x12, /// entry: int64
  230. 'e', 'n', 't', 'r', 'y', '\x00',
  231. 0x01, 0x02, 0x03, 0x04, 0x78, 0x56, 0x34, 0x12,
  232. 0x00 // end marker
  233. };
  234. const auto result = json::to_bson(j);
  235. CHECK(result == expected);
  236. // roundtrip
  237. CHECK(json::from_bson(result) == j);
  238. CHECK(json::from_bson(result, true, false) == j);
  239. }
  240. SECTION("non-empty object with negative integer (32-bit) member")
  241. {
  242. json const j =
  243. {
  244. { "entry", std::int32_t{-1} }
  245. };
  246. std::vector<std::uint8_t> const expected =
  247. {
  248. 0x10, 0x00, 0x00, 0x00, // size (little endian)
  249. 0x10, /// entry: int32
  250. 'e', 'n', 't', 'r', 'y', '\x00',
  251. 0xFF, 0xFF, 0xFF, 0xFF,
  252. 0x00 // end marker
  253. };
  254. const auto result = json::to_bson(j);
  255. CHECK(result == expected);
  256. // roundtrip
  257. CHECK(json::from_bson(result) == j);
  258. CHECK(json::from_bson(result, true, false) == j);
  259. }
  260. SECTION("non-empty object with negative integer (64-bit) member")
  261. {
  262. json const j =
  263. {
  264. { "entry", std::int64_t{-1} }
  265. };
  266. std::vector<std::uint8_t> const expected =
  267. {
  268. 0x10, 0x00, 0x00, 0x00, // size (little endian)
  269. 0x10, /// entry: int32
  270. 'e', 'n', 't', 'r', 'y', '\x00',
  271. 0xFF, 0xFF, 0xFF, 0xFF,
  272. 0x00 // end marker
  273. };
  274. const auto result = json::to_bson(j);
  275. CHECK(result == expected);
  276. // roundtrip
  277. CHECK(json::from_bson(result) == j);
  278. CHECK(json::from_bson(result, true, false) == j);
  279. }
  280. SECTION("non-empty object with unsigned integer (64-bit) member")
  281. {
  282. // directly encoding uint64 is not supported in bson (only for timestamp values)
  283. json const j =
  284. {
  285. { "entry", std::uint64_t{0x1234567804030201} }
  286. };
  287. std::vector<std::uint8_t> const expected =
  288. {
  289. 0x14, 0x00, 0x00, 0x00, // size (little endian)
  290. 0x12, /// entry: int64
  291. 'e', 'n', 't', 'r', 'y', '\x00',
  292. 0x01, 0x02, 0x03, 0x04, 0x78, 0x56, 0x34, 0x12,
  293. 0x00 // end marker
  294. };
  295. const auto result = json::to_bson(j);
  296. CHECK(result == expected);
  297. // roundtrip
  298. CHECK(json::from_bson(result) == j);
  299. CHECK(json::from_bson(result, true, false) == j);
  300. }
  301. SECTION("non-empty object with small unsigned integer member")
  302. {
  303. json const j =
  304. {
  305. { "entry", std::uint64_t{0x42} }
  306. };
  307. std::vector<std::uint8_t> const expected =
  308. {
  309. 0x10, 0x00, 0x00, 0x00, // size (little endian)
  310. 0x10, /// entry: int32
  311. 'e', 'n', 't', 'r', 'y', '\x00',
  312. 0x42, 0x00, 0x00, 0x00,
  313. 0x00 // end marker
  314. };
  315. const auto result = json::to_bson(j);
  316. CHECK(result == expected);
  317. // roundtrip
  318. CHECK(json::from_bson(result) == j);
  319. CHECK(json::from_bson(result, true, false) == j);
  320. }
  321. SECTION("non-empty object with object member")
  322. {
  323. json const j =
  324. {
  325. { "entry", json::object() }
  326. };
  327. std::vector<std::uint8_t> const expected =
  328. {
  329. 0x11, 0x00, 0x00, 0x00, // size (little endian)
  330. 0x03, /// entry: embedded document
  331. 'e', 'n', 't', 'r', 'y', '\x00',
  332. 0x05, 0x00, 0x00, 0x00, // size (little endian)
  333. // no entries
  334. 0x00, // end marker (embedded document)
  335. 0x00 // end marker
  336. };
  337. const auto result = json::to_bson(j);
  338. CHECK(result == expected);
  339. // roundtrip
  340. CHECK(json::from_bson(result) == j);
  341. CHECK(json::from_bson(result, true, false) == j);
  342. }
  343. SECTION("non-empty object with array member")
  344. {
  345. json const j =
  346. {
  347. { "entry", json::array() }
  348. };
  349. std::vector<std::uint8_t> const expected =
  350. {
  351. 0x11, 0x00, 0x00, 0x00, // size (little endian)
  352. 0x04, /// entry: embedded document
  353. 'e', 'n', 't', 'r', 'y', '\x00',
  354. 0x05, 0x00, 0x00, 0x00, // size (little endian)
  355. // no entries
  356. 0x00, // end marker (embedded document)
  357. 0x00 // end marker
  358. };
  359. const auto result = json::to_bson(j);
  360. CHECK(result == expected);
  361. // roundtrip
  362. CHECK(json::from_bson(result) == j);
  363. CHECK(json::from_bson(result, true, false) == j);
  364. }
  365. SECTION("non-empty object with non-empty array member")
  366. {
  367. json const j =
  368. {
  369. { "entry", json::array({1, 2, 3, 4, 5, 6, 7, 8}) }
  370. };
  371. std::vector<std::uint8_t> const expected =
  372. {
  373. 0x49, 0x00, 0x00, 0x00, // size (little endian)
  374. 0x04, /// entry: embedded document
  375. 'e', 'n', 't', 'r', 'y', '\x00',
  376. 0x3D, 0x00, 0x00, 0x00, // size (little endian)
  377. 0x10, '0', 0x00, 0x01, 0x00, 0x00, 0x00,
  378. 0x10, '1', 0x00, 0x02, 0x00, 0x00, 0x00,
  379. 0x10, '2', 0x00, 0x03, 0x00, 0x00, 0x00,
  380. 0x10, '3', 0x00, 0x04, 0x00, 0x00, 0x00,
  381. 0x10, '4', 0x00, 0x05, 0x00, 0x00, 0x00,
  382. 0x10, '5', 0x00, 0x06, 0x00, 0x00, 0x00,
  383. 0x10, '6', 0x00, 0x07, 0x00, 0x00, 0x00,
  384. 0x10, '7', 0x00, 0x08, 0x00, 0x00, 0x00,
  385. 0x00, // end marker (embedded document)
  386. 0x00 // end marker
  387. };
  388. const auto result = json::to_bson(j);
  389. CHECK(result == expected);
  390. // roundtrip
  391. CHECK(json::from_bson(result) == j);
  392. CHECK(json::from_bson(result, true, false) == j);
  393. }
  394. SECTION("non-empty object with binary member")
  395. {
  396. const size_t N = 10;
  397. const auto s = std::vector<std::uint8_t>(N, 'x');
  398. json const j =
  399. {
  400. { "entry", json::binary(s, 0) }
  401. };
  402. std::vector<std::uint8_t> const expected =
  403. {
  404. 0x1B, 0x00, 0x00, 0x00, // size (little endian)
  405. 0x05, // entry: binary
  406. 'e', 'n', 't', 'r', 'y', '\x00',
  407. 0x0A, 0x00, 0x00, 0x00, // size of binary (little endian)
  408. 0x00, // Generic binary subtype
  409. 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
  410. 0x00 // end marker
  411. };
  412. const auto result = json::to_bson(j);
  413. CHECK(result == expected);
  414. // roundtrip
  415. CHECK(json::from_bson(result) == j);
  416. CHECK(json::from_bson(result, true, false) == j);
  417. }
  418. SECTION("non-empty object with binary member with subtype")
  419. {
  420. // an MD5 hash
  421. const std::vector<std::uint8_t> md5hash = {0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4};
  422. json const j =
  423. {
  424. { "entry", json::binary(md5hash, 5) }
  425. };
  426. std::vector<std::uint8_t> const expected =
  427. {
  428. 0x21, 0x00, 0x00, 0x00, // size (little endian)
  429. 0x05, // entry: binary
  430. 'e', 'n', 't', 'r', 'y', '\x00',
  431. 0x10, 0x00, 0x00, 0x00, // size of binary (little endian)
  432. 0x05, // MD5 binary subtype
  433. 0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4,
  434. 0x00 // end marker
  435. };
  436. const auto result = json::to_bson(j);
  437. CHECK(result == expected);
  438. // roundtrip
  439. CHECK(json::from_bson(result) == j);
  440. CHECK(json::from_bson(result, true, false) == j);
  441. }
  442. SECTION("Some more complex document")
  443. {
  444. // directly encoding uint64 is not supported in bson (only for timestamp values)
  445. json const j =
  446. {
  447. {"double", 42.5},
  448. {"entry", 4.2},
  449. {"number", 12345},
  450. {"object", {{ "string", "value" }}}
  451. };
  452. std::vector<std::uint8_t> const expected =
  453. {
  454. /*size */ 0x4f, 0x00, 0x00, 0x00,
  455. /*entry*/ 0x01, 'd', 'o', 'u', 'b', 'l', 'e', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x40,
  456. /*entry*/ 0x01, 'e', 'n', 't', 'r', 'y', 0x00, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,
  457. /*entry*/ 0x10, 'n', 'u', 'm', 'b', 'e', 'r', 0x00, 0x39, 0x30, 0x00, 0x00,
  458. /*entry*/ 0x03, 'o', 'b', 'j', 'e', 'c', 't', 0x00,
  459. /*entry: obj-size */ 0x17, 0x00, 0x00, 0x00,
  460. /*entry: obj-entry*/0x02, 's', 't', 'r', 'i', 'n', 'g', 0x00, 0x06, 0x00, 0x00, 0x00, 'v', 'a', 'l', 'u', 'e', 0,
  461. /*entry: obj-term.*/0x00,
  462. /*obj-term*/ 0x00
  463. };
  464. const auto result = json::to_bson(j);
  465. CHECK(result == expected);
  466. // roundtrip
  467. CHECK(json::from_bson(result) == j);
  468. CHECK(json::from_bson(result, true, false) == j);
  469. }
  470. }
  471. SECTION("Examples from http://bsonspec.org/faq.html")
  472. {
  473. SECTION("Example 1")
  474. {
  475. std::vector<std::uint8_t> input = {0x16, 0x00, 0x00, 0x00, 0x02, 'h', 'e', 'l', 'l', 'o', 0x00, 0x06, 0x00, 0x00, 0x00, 'w', 'o', 'r', 'l', 'd', 0x00, 0x00};
  476. json parsed = json::from_bson(input);
  477. json expected = {{"hello", "world"}};
  478. CHECK(parsed == expected);
  479. auto dumped = json::to_bson(parsed);
  480. CHECK(dumped == input);
  481. CHECK(json::from_bson(dumped) == expected);
  482. }
  483. SECTION("Example 2")
  484. {
  485. std::vector<std::uint8_t> input = {0x31, 0x00, 0x00, 0x00, 0x04, 'B', 'S', 'O', 'N', 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 'a', 'w', 'e', 's', 'o', 'm', 'e', 0x00, 0x01, 0x31, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x14, 0x40, 0x10, 0x32, 0x00, 0xc2, 0x07, 0x00, 0x00, 0x00, 0x00};
  486. json parsed = json::from_bson(input);
  487. json expected = {{"BSON", {"awesome", 5.05, 1986}}};
  488. CHECK(parsed == expected);
  489. auto dumped = json::to_bson(parsed);
  490. CHECK(dumped == input);
  491. CHECK(json::from_bson(dumped) == expected);
  492. }
  493. }
  494. }
  495. TEST_CASE("BSON input/output_adapters")
  496. {
  497. json json_representation =
  498. {
  499. {"double", 42.5},
  500. {"entry", 4.2},
  501. {"number", 12345},
  502. {"object", {{ "string", "value" }}}
  503. };
  504. std::vector<std::uint8_t> const bson_representation =
  505. {
  506. /*size */ 0x4f, 0x00, 0x00, 0x00,
  507. /*entry*/ 0x01, 'd', 'o', 'u', 'b', 'l', 'e', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x45, 0x40,
  508. /*entry*/ 0x01, 'e', 'n', 't', 'r', 'y', 0x00, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40,
  509. /*entry*/ 0x10, 'n', 'u', 'm', 'b', 'e', 'r', 0x00, 0x39, 0x30, 0x00, 0x00,
  510. /*entry*/ 0x03, 'o', 'b', 'j', 'e', 'c', 't', 0x00,
  511. /*entry: obj-size */ 0x17, 0x00, 0x00, 0x00,
  512. /*entry: obj-entry*/0x02, 's', 't', 'r', 'i', 'n', 'g', 0x00, 0x06, 0x00, 0x00, 0x00, 'v', 'a', 'l', 'u', 'e', 0,
  513. /*entry: obj-term.*/0x00,
  514. /*obj-term*/ 0x00
  515. };
  516. json j2;
  517. CHECK_NOTHROW(j2 = json::from_bson(bson_representation));
  518. // compare parsed JSON values
  519. CHECK(json_representation == j2);
  520. SECTION("roundtrips")
  521. {
  522. SECTION("std::ostringstream")
  523. {
  524. std::basic_ostringstream<std::uint8_t> ss;
  525. json::to_bson(json_representation, ss);
  526. json j3 = json::from_bson(ss.str());
  527. CHECK(json_representation == j3);
  528. }
  529. SECTION("std::string")
  530. {
  531. std::string s;
  532. json::to_bson(json_representation, s);
  533. json j3 = json::from_bson(s);
  534. CHECK(json_representation == j3);
  535. }
  536. SECTION("std::vector")
  537. {
  538. std::vector<std::uint8_t> v;
  539. json::to_bson(json_representation, v);
  540. json j3 = json::from_bson(v);
  541. CHECK(json_representation == j3);
  542. }
  543. }
  544. }
  545. namespace
  546. {
  547. class SaxCountdown
  548. {
  549. public:
  550. explicit SaxCountdown(const int count) : events_left(count)
  551. {}
  552. bool null()
  553. {
  554. return events_left-- > 0;
  555. }
  556. bool boolean(bool /*unused*/)
  557. {
  558. return events_left-- > 0;
  559. }
  560. bool number_integer(json::number_integer_t /*unused*/)
  561. {
  562. return events_left-- > 0;
  563. }
  564. bool number_unsigned(json::number_unsigned_t /*unused*/)
  565. {
  566. return events_left-- > 0;
  567. }
  568. bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
  569. {
  570. return events_left-- > 0;
  571. }
  572. bool string(std::string& /*unused*/)
  573. {
  574. return events_left-- > 0;
  575. }
  576. bool binary(std::vector<std::uint8_t>& /*unused*/)
  577. {
  578. return events_left-- > 0;
  579. }
  580. bool start_object(std::size_t /*unused*/)
  581. {
  582. return events_left-- > 0;
  583. }
  584. bool key(std::string& /*unused*/)
  585. {
  586. return events_left-- > 0;
  587. }
  588. bool end_object()
  589. {
  590. return events_left-- > 0;
  591. }
  592. bool start_array(std::size_t /*unused*/)
  593. {
  594. return events_left-- > 0;
  595. }
  596. bool end_array()
  597. {
  598. return events_left-- > 0;
  599. }
  600. bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
  601. {
  602. return false;
  603. }
  604. private:
  605. int events_left = 0;
  606. };
  607. } // namespace
  608. TEST_CASE("Incomplete BSON Input")
  609. {
  610. SECTION("Incomplete BSON Input 1")
  611. {
  612. std::vector<std::uint8_t> const incomplete_bson =
  613. {
  614. 0x0D, 0x00, 0x00, 0x00, // size (little endian)
  615. 0x08, // entry: boolean
  616. 'e', 'n', 't' // unexpected EOF
  617. };
  618. json _;
  619. CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing BSON cstring: unexpected end of input", json::parse_error&);
  620. CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
  621. SaxCountdown scp(0);
  622. CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
  623. }
  624. SECTION("Incomplete BSON Input 2")
  625. {
  626. std::vector<std::uint8_t> const incomplete_bson =
  627. {
  628. 0x0D, 0x00, 0x00, 0x00, // size (little endian)
  629. 0x08, // entry: boolean, unexpected EOF
  630. };
  631. json _;
  632. CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing BSON cstring: unexpected end of input", json::parse_error&);
  633. CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
  634. SaxCountdown scp(0);
  635. CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
  636. }
  637. SECTION("Incomplete BSON Input 3")
  638. {
  639. std::vector<std::uint8_t> const incomplete_bson =
  640. {
  641. 0x41, 0x00, 0x00, 0x00, // size (little endian)
  642. 0x04, /// entry: embedded document
  643. 'e', 'n', 't', 'r', 'y', '\x00',
  644. 0x35, 0x00, 0x00, 0x00, // size (little endian)
  645. 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
  646. 0x10, 0x00, 0x02, 0x00, 0x00, 0x00
  647. // missing input data...
  648. };
  649. json _;
  650. CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 28: syntax error while parsing BSON element list: unexpected end of input", json::parse_error&);
  651. CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
  652. SaxCountdown scp(1);
  653. CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
  654. }
  655. SECTION("Incomplete BSON Input 4")
  656. {
  657. std::vector<std::uint8_t> const incomplete_bson =
  658. {
  659. 0x0D, 0x00, // size (incomplete), unexpected EOF
  660. };
  661. json _;
  662. CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing BSON number: unexpected end of input", json::parse_error&);
  663. CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());
  664. SaxCountdown scp(0);
  665. CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
  666. }
  667. SECTION("Improve coverage")
  668. {
  669. SECTION("key")
  670. {
  671. json const j = {{"key", "value"}};
  672. auto bson_vec = json::to_bson(j);
  673. SaxCountdown scp(2);
  674. CHECK(!json::sax_parse(bson_vec, &scp, json::input_format_t::bson));
  675. }
  676. SECTION("array")
  677. {
  678. json const j =
  679. {
  680. { "entry", json::array() }
  681. };
  682. auto bson_vec = json::to_bson(j);
  683. SaxCountdown scp(2);
  684. CHECK(!json::sax_parse(bson_vec, &scp, json::input_format_t::bson));
  685. }
  686. }
  687. }
  688. TEST_CASE("Negative size of binary value")
  689. {
  690. // invalid BSON: the size of the binary value is -1
  691. std::vector<std::uint8_t> const input =
  692. {
  693. 0x21, 0x00, 0x00, 0x00, // size (little endian)
  694. 0x05, // entry: binary
  695. 'e', 'n', 't', 'r', 'y', '\x00',
  696. 0xFF, 0xFF, 0xFF, 0xFF, // size of binary (little endian)
  697. 0x05, // MD5 binary subtype
  698. 0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4,
  699. 0x00 // end marker
  700. };
  701. json _;
  702. CHECK_THROWS_WITH_AS(_ = json::from_bson(input), "[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1", json::parse_error);
  703. }
  704. TEST_CASE("Unsupported BSON input")
  705. {
  706. std::vector<std::uint8_t> const bson =
  707. {
  708. 0x0C, 0x00, 0x00, 0x00, // size (little endian)
  709. 0xFF, // entry type: Min key (not supported yet)
  710. 'e', 'n', 't', 'r', 'y', '\x00',
  711. 0x00 // end marker
  712. };
  713. json _;
  714. CHECK_THROWS_WITH_AS(_ = json::from_bson(bson), "[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF", json::parse_error&);
  715. CHECK(json::from_bson(bson, true, false).is_discarded());
  716. SaxCountdown scp(0);
  717. CHECK(!json::sax_parse(bson, &scp, json::input_format_t::bson));
  718. }
  719. TEST_CASE("BSON numerical data")
  720. {
  721. SECTION("number")
  722. {
  723. SECTION("signed")
  724. {
  725. SECTION("std::int64_t: INT64_MIN .. INT32_MIN-1")
  726. {
  727. std::vector<int64_t> const numbers
  728. {
  729. (std::numeric_limits<int64_t>::min)(),
  730. -1000000000000000000LL,
  731. -100000000000000000LL,
  732. -10000000000000000LL,
  733. -1000000000000000LL,
  734. -100000000000000LL,
  735. -10000000000000LL,
  736. -1000000000000LL,
  737. -100000000000LL,
  738. -10000000000LL,
  739. static_cast<std::int64_t>((std::numeric_limits<std::int32_t>::min)()) - 1,
  740. };
  741. for (const auto i : numbers)
  742. {
  743. CAPTURE(i)
  744. json const j =
  745. {
  746. { "entry", i }
  747. };
  748. CHECK(j.at("entry").is_number_integer());
  749. std::uint64_t const iu = *reinterpret_cast<const std::uint64_t*>(&i);
  750. std::vector<std::uint8_t> const expected_bson =
  751. {
  752. 0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)
  753. 0x12u, /// entry: int64
  754. 'e', 'n', 't', 'r', 'y', '\x00',
  755. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  756. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  757. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  758. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  759. static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),
  760. static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),
  761. static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),
  762. static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),
  763. 0x00u // end marker
  764. };
  765. const auto bson = json::to_bson(j);
  766. CHECK(bson == expected_bson);
  767. auto j_roundtrip = json::from_bson(bson);
  768. CHECK(j_roundtrip.at("entry").is_number_integer());
  769. CHECK(j_roundtrip == j);
  770. CHECK(json::from_bson(bson, true, false) == j);
  771. }
  772. }
  773. SECTION("signed std::int32_t: INT32_MIN .. INT32_MAX")
  774. {
  775. std::vector<int32_t> const numbers
  776. {
  777. (std::numeric_limits<int32_t>::min)(),
  778. -2147483647L,
  779. -1000000000L,
  780. -100000000L,
  781. -10000000L,
  782. -1000000L,
  783. -100000L,
  784. -10000L,
  785. -1000L,
  786. -100L,
  787. -10L,
  788. -1L,
  789. 0L,
  790. 1L,
  791. 10L,
  792. 100L,
  793. 1000L,
  794. 10000L,
  795. 100000L,
  796. 1000000L,
  797. 10000000L,
  798. 100000000L,
  799. 1000000000L,
  800. 2147483646L,
  801. (std::numeric_limits<int32_t>::max)()
  802. };
  803. for (const auto i : numbers)
  804. {
  805. CAPTURE(i)
  806. json const j =
  807. {
  808. { "entry", i }
  809. };
  810. CHECK(j.at("entry").is_number_integer());
  811. std::uint32_t const iu = *reinterpret_cast<const std::uint32_t*>(&i);
  812. std::vector<std::uint8_t> const expected_bson =
  813. {
  814. 0x10u, 0x00u, 0x00u, 0x00u, // size (little endian)
  815. 0x10u, /// entry: int32
  816. 'e', 'n', 't', 'r', 'y', '\x00',
  817. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  818. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  819. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  820. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  821. 0x00u // end marker
  822. };
  823. const auto bson = json::to_bson(j);
  824. CHECK(bson == expected_bson);
  825. auto j_roundtrip = json::from_bson(bson);
  826. CHECK(j_roundtrip.at("entry").is_number_integer());
  827. CHECK(j_roundtrip == j);
  828. CHECK(json::from_bson(bson, true, false) == j);
  829. }
  830. }
  831. SECTION("signed std::int64_t: INT32_MAX+1 .. INT64_MAX")
  832. {
  833. std::vector<int64_t> const numbers
  834. {
  835. (std::numeric_limits<int64_t>::max)(),
  836. 1000000000000000000LL,
  837. 100000000000000000LL,
  838. 10000000000000000LL,
  839. 1000000000000000LL,
  840. 100000000000000LL,
  841. 10000000000000LL,
  842. 1000000000000LL,
  843. 100000000000LL,
  844. 10000000000LL,
  845. static_cast<std::int64_t>((std::numeric_limits<int32_t>::max)()) + 1,
  846. };
  847. for (const auto i : numbers)
  848. {
  849. CAPTURE(i)
  850. json const j =
  851. {
  852. { "entry", i }
  853. };
  854. CHECK(j.at("entry").is_number_integer());
  855. std::uint64_t const iu = *reinterpret_cast<const std::uint64_t*>(&i);
  856. std::vector<std::uint8_t> const expected_bson =
  857. {
  858. 0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)
  859. 0x12u, /// entry: int64
  860. 'e', 'n', 't', 'r', 'y', '\x00',
  861. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  862. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  863. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  864. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  865. static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),
  866. static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),
  867. static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),
  868. static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),
  869. 0x00u // end marker
  870. };
  871. const auto bson = json::to_bson(j);
  872. CHECK(bson == expected_bson);
  873. auto j_roundtrip = json::from_bson(bson);
  874. CHECK(j_roundtrip.at("entry").is_number_integer());
  875. CHECK(j_roundtrip == j);
  876. CHECK(json::from_bson(bson, true, false) == j);
  877. }
  878. }
  879. }
  880. SECTION("unsigned")
  881. {
  882. SECTION("unsigned std::uint64_t: 0 .. INT32_MAX")
  883. {
  884. std::vector<std::uint64_t> const numbers
  885. {
  886. 0ULL,
  887. 1ULL,
  888. 10ULL,
  889. 100ULL,
  890. 1000ULL,
  891. 10000ULL,
  892. 100000ULL,
  893. 1000000ULL,
  894. 10000000ULL,
  895. 100000000ULL,
  896. 1000000000ULL,
  897. 2147483646ULL,
  898. static_cast<std::uint64_t>((std::numeric_limits<int32_t>::max)())
  899. };
  900. for (const auto i : numbers)
  901. {
  902. CAPTURE(i)
  903. json const j =
  904. {
  905. { "entry", i }
  906. };
  907. auto iu = i;
  908. std::vector<std::uint8_t> const expected_bson =
  909. {
  910. 0x10u, 0x00u, 0x00u, 0x00u, // size (little endian)
  911. 0x10u, /// entry: int32
  912. 'e', 'n', 't', 'r', 'y', '\x00',
  913. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  914. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  915. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  916. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  917. 0x00u // end marker
  918. };
  919. const auto bson = json::to_bson(j);
  920. CHECK(bson == expected_bson);
  921. auto j_roundtrip = json::from_bson(bson);
  922. CHECK(j.at("entry").is_number_unsigned());
  923. CHECK(j_roundtrip.at("entry").is_number_integer());
  924. CHECK(j_roundtrip == j);
  925. CHECK(json::from_bson(bson, true, false) == j);
  926. }
  927. }
  928. SECTION("unsigned std::uint64_t: INT32_MAX+1 .. INT64_MAX")
  929. {
  930. std::vector<std::uint64_t> const numbers
  931. {
  932. static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()) + 1,
  933. 4000000000ULL,
  934. static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()),
  935. 10000000000ULL,
  936. 100000000000ULL,
  937. 1000000000000ULL,
  938. 10000000000000ULL,
  939. 100000000000000ULL,
  940. 1000000000000000ULL,
  941. 10000000000000000ULL,
  942. 100000000000000000ULL,
  943. 1000000000000000000ULL,
  944. static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()),
  945. };
  946. for (const auto i : numbers)
  947. {
  948. CAPTURE(i)
  949. json const j =
  950. {
  951. { "entry", i }
  952. };
  953. auto iu = i;
  954. std::vector<std::uint8_t> const expected_bson =
  955. {
  956. 0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)
  957. 0x12u, /// entry: int64
  958. 'e', 'n', 't', 'r', 'y', '\x00',
  959. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  960. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  961. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  962. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  963. static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),
  964. static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),
  965. static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),
  966. static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),
  967. 0x00u // end marker
  968. };
  969. const auto bson = json::to_bson(j);
  970. CHECK(bson == expected_bson);
  971. auto j_roundtrip = json::from_bson(bson);
  972. CHECK(j.at("entry").is_number_unsigned());
  973. CHECK(j_roundtrip.at("entry").is_number_integer());
  974. CHECK(j_roundtrip == j);
  975. CHECK(json::from_bson(bson, true, false) == j);
  976. }
  977. }
  978. SECTION("unsigned std::uint64_t: INT64_MAX+1 .. UINT64_MAX")
  979. {
  980. std::vector<std::uint64_t> const numbers
  981. {
  982. static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()) + 1ULL,
  983. 10000000000000000000ULL,
  984. 18000000000000000000ULL,
  985. (std::numeric_limits<std::uint64_t>::max)() - 1ULL,
  986. (std::numeric_limits<std::uint64_t>::max)(),
  987. };
  988. for (const auto i : numbers)
  989. {
  990. CAPTURE(i)
  991. json const j =
  992. {
  993. { "entry", i }
  994. };
  995. auto iu = i;
  996. std::vector<std::uint8_t> const expected_bson =
  997. {
  998. 0x14u, 0x00u, 0x00u, 0x00u, // size (little endian)
  999. 0x12u, /// entry: int64
  1000. 'e', 'n', 't', 'r', 'y', '\x00',
  1001. static_cast<std::uint8_t>((iu >> (8u * 0u)) & 0xffu),
  1002. static_cast<std::uint8_t>((iu >> (8u * 1u)) & 0xffu),
  1003. static_cast<std::uint8_t>((iu >> (8u * 2u)) & 0xffu),
  1004. static_cast<std::uint8_t>((iu >> (8u * 3u)) & 0xffu),
  1005. static_cast<std::uint8_t>((iu >> (8u * 4u)) & 0xffu),
  1006. static_cast<std::uint8_t>((iu >> (8u * 5u)) & 0xffu),
  1007. static_cast<std::uint8_t>((iu >> (8u * 6u)) & 0xffu),
  1008. static_cast<std::uint8_t>((iu >> (8u * 7u)) & 0xffu),
  1009. 0x00u // end marker
  1010. };
  1011. CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);
  1012. #if JSON_DIAGNOSTICS
  1013. CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] (/entry) integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
  1014. #else
  1015. CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
  1016. #endif
  1017. }
  1018. }
  1019. }
  1020. }
  1021. }
  1022. TEST_CASE("BSON roundtrips" * doctest::skip())
  1023. {
  1024. SECTION("reference files")
  1025. {
  1026. for (const std::string filename :
  1027. {
  1028. TEST_DATA_DIRECTORY "/json.org/1.json",
  1029. TEST_DATA_DIRECTORY "/json.org/2.json",
  1030. TEST_DATA_DIRECTORY "/json.org/3.json",
  1031. TEST_DATA_DIRECTORY "/json.org/4.json",
  1032. TEST_DATA_DIRECTORY "/json.org/5.json"
  1033. })
  1034. {
  1035. CAPTURE(filename)
  1036. {
  1037. INFO_WITH_TEMP(filename + ": std::vector<std::uint8_t>");
  1038. // parse JSON file
  1039. std::ifstream f_json(filename);
  1040. json j1 = json::parse(f_json);
  1041. // parse BSON file
  1042. auto packed = utils::read_binary_file(filename + ".bson");
  1043. json j2;
  1044. CHECK_NOTHROW(j2 = json::from_bson(packed));
  1045. // compare parsed JSON values
  1046. CHECK(j1 == j2);
  1047. }
  1048. {
  1049. INFO_WITH_TEMP(filename + ": std::ifstream");
  1050. // parse JSON file
  1051. std::ifstream f_json(filename);
  1052. json j1 = json::parse(f_json);
  1053. // parse BSON file
  1054. std::ifstream f_bson(filename + ".bson", std::ios::binary);
  1055. json j2;
  1056. CHECK_NOTHROW(j2 = json::from_bson(f_bson));
  1057. // compare parsed JSON values
  1058. CHECK(j1 == j2);
  1059. }
  1060. {
  1061. INFO_WITH_TEMP(filename + ": uint8_t* and size");
  1062. // parse JSON file
  1063. std::ifstream f_json(filename);
  1064. json j1 = json::parse(f_json);
  1065. // parse BSON file
  1066. auto packed = utils::read_binary_file(filename + ".bson");
  1067. json j2;
  1068. CHECK_NOTHROW(j2 = json::from_bson({packed.data(), packed.size()}));
  1069. // compare parsed JSON values
  1070. CHECK(j1 == j2);
  1071. }
  1072. {
  1073. INFO_WITH_TEMP(filename + ": output to output adapters");
  1074. // parse JSON file
  1075. std::ifstream f_json(filename);
  1076. json const j1 = json::parse(f_json);
  1077. // parse BSON file
  1078. auto packed = utils::read_binary_file(filename + ".bson");
  1079. {
  1080. INFO_WITH_TEMP(filename + ": output adapters: std::vector<std::uint8_t>");
  1081. std::vector<std::uint8_t> vec;
  1082. json::to_bson(j1, vec);
  1083. if (vec != packed)
  1084. {
  1085. // the exact serializations may differ due to the order of
  1086. // object keys; in these cases, just compare whether both
  1087. // serializations create the same JSON value
  1088. CHECK(json::from_bson(vec) == json::from_bson(packed));
  1089. }
  1090. }
  1091. }
  1092. }
  1093. }
  1094. }