unit-bson.cpp 45 KB

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