diff --git a/include/nlohmann/detail/exceptions.hpp b/include/nlohmann/detail/exceptions.hpp index 5b0420e2..1ac2606b 100644 --- a/include/nlohmann/detail/exceptions.hpp +++ b/include/nlohmann/detail/exceptions.hpp @@ -282,7 +282,7 @@ json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch op json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. | json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | +json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | @liveexample{The following code shows how an `out_of_range` exception can be caught.,out_of_range} diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index f659476e..bebfa936 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -683,9 +683,11 @@ class binary_writer */ static std::size_t calc_bson_entry_header_size(const typename BasicJsonType::string_t& name) { - if (name.find(static_cast(0)) != BasicJsonType::string_t::npos) + const auto it = name.find(static_cast(0)); + if (it != BasicJsonType::string_t::npos) { - JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000")); + JSON_THROW(out_of_range::create(409, + "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")")); } return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e739eb5c..bbcef784 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -923,7 +923,7 @@ json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch op json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. | json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | +json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | @liveexample{The following code shows how an `out_of_range` exception can be caught.,out_of_range} @@ -8840,9 +8840,11 @@ class binary_writer */ static std::size_t calc_bson_entry_header_size(const typename BasicJsonType::string_t& name) { - if (name.find(static_cast(0)) != BasicJsonType::string_t::npos) + const auto it = name.find(static_cast(0)); + if (it != BasicJsonType::string_t::npos) { - JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000")); + JSON_THROW(out_of_range::create(409, + "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")")); } return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; diff --git a/test/src/unit-bson.cpp b/test/src/unit-bson.cpp index 633dbd2e..3449b698 100644 --- a/test/src/unit-bson.cpp +++ b/test/src/unit-bson.cpp @@ -48,7 +48,8 @@ TEST_CASE("BSON") SECTION("null") { json j = nullptr; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 0 cannot be serialized to requested format"); } SECTION("boolean") @@ -56,38 +57,44 @@ TEST_CASE("BSON") SECTION("true") { json j = true; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 4 cannot be serialized to requested format"); } SECTION("false") { json j = false; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 4 cannot be serialized to requested format"); } } SECTION("number") { json j = 42; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 5 cannot be serialized to requested format"); } SECTION("float") { json j = 4.2; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 7 cannot be serialized to requested format"); } SECTION("string") { json j = "not supported"; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 3 cannot be serialized to requested format"); } SECTION("array") { json j = std::vector {1, 2, 3, 4, 5, 6, 7}; - REQUIRE_THROWS_AS(json::to_bson(j), json::type_error); + REQUIRE_THROWS_AS(json::to_bson(j), json::type_error&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.type_error.317] JSON value of type 2 cannot be serialized to requested format"); } } @@ -97,8 +104,8 @@ TEST_CASE("BSON") { { std::string("en\0try", 6), true } }; - REQUIRE_THROWS_AS(json::to_bson(j), json::out_of_range); - CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.out_of_range.409] BSON key cannot contain code point U+0000"); + REQUIRE_THROWS_AS(json::to_bson(j), json::out_of_range&); + CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)"); } SECTION("objects") @@ -678,6 +685,7 @@ TEST_CASE("Incomplete BSON INPUT") 'e', 'n', 't' // unexpected EOF }; + CHECK_THROWS_AS(json::from_bson(incomplete_bson), json::parse_error&); CHECK_THROWS_WITH(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"); @@ -695,6 +703,7 @@ TEST_CASE("Incomplete BSON INPUT 2") 0x08, // entry: boolean, unexpected EOF }; + CHECK_THROWS_AS(json::from_bson(incomplete_bson), json::parse_error&); CHECK_THROWS_WITH(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"); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); @@ -717,6 +726,8 @@ TEST_CASE("Incomplete BSON INPUT 3") 0x10, 0x00, 0x02, 0x00, 0x00, 0x00 // missing input data... }; + + CHECK_THROWS_AS(json::from_bson(incomplete_bson), json::parse_error&); CHECK_THROWS_WITH(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"); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); @@ -734,6 +745,7 @@ TEST_CASE("Incomplete BSON INPUT 4") 0x0D, 0x00, // size (incomplete), unexpected EOF }; + CHECK_THROWS_AS(json::from_bson(incomplete_bson), json::parse_error&); CHECK_THROWS_WITH(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"); CHECK(json::from_bson(incomplete_bson, true, false).is_discarded()); @@ -753,6 +765,7 @@ TEST_CASE("Unsupported BSON input") 0x00 // end marker }; + CHECK_THROWS_AS(json::from_bson(bson), json::parse_error&); CHECK_THROWS_WITH(json::from_bson(bson), "[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF"); CHECK(json::from_bson(bson, true, false).is_discarded());