diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index fe2b233ad..ebdeef26f 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -1918,14 +1918,11 @@ class binary_reader } } auto last_token = get_token_string(); - if (input_format != input_format_t::bjdata) - { - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), nullptr)); - } - else + if (input_format == input_format_t::bjdata) { return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, u, l, m, L, M); last byte: 0x" + last_token, "string"), nullptr)); } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType())); } /*! @@ -2122,14 +2119,11 @@ class binary_reader } } auto last_token = get_token_string(); - if (input_format != input_format_t::bjdata) - { - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), nullptr)); - } - else + if (input_format == input_format_t::bjdata) { return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, u, l, m, L, M) after '#'; last byte: 0x" + last_token, "size"), nullptr)); } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType())); } /*! diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index f121ef667..490cf63bb 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -37,11 +37,12 @@ class binary_writer @brief create a binary writer @param[in] adapter output adapter to write to + @param[in] is_bjdata_ a boolean, if true, output is BJData format, default is false */ - explicit binary_writer(output_adapter_t adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)) + explicit binary_writer(output_adapter_t adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)), is_bjdata(is_bjdata_) { JSON_ASSERT(oa); - is_bjdata = is_bjdata_; + JSON_ASSERT(is_bjdata); } /*! diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index d232b2f7a..d33fd3b3c 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4177,8 +4177,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } - /// @brief create a JSON value from an input in UBJSON format - /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ + /// @brief create a JSON value from an input in BJData format + /// @sa https://github.com/NeuroJSON/bjdata/blob/master/Binary_JData_Specification.md template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bjdata(InputType&& i, @@ -4209,7 +4209,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bjdata(ptr, ptr + len)) static basic_json from_bjdata(const T* ptr, std::size_t len, const bool strict = true, const bool allow_exceptions = true) @@ -4218,7 +4217,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bjdata(ptr, ptr + len)) static basic_json from_bjdata(detail::span_input_adapter&& i, const bool strict = true, const bool allow_exceptions = true) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 344026d3f..7e01ab952 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -10294,14 +10294,11 @@ class binary_reader } } auto last_token = get_token_string(); - if (input_format != input_format_t::bjdata) - { - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), nullptr)); - } - else + if (input_format == input_format_t::bjdata) { return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, u, l, m, L, M); last byte: 0x" + last_token, "string"), nullptr)); } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType())); } /*! @@ -10498,14 +10495,11 @@ class binary_reader } } auto last_token = get_token_string(); - if (input_format != input_format_t::bjdata) - { - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), nullptr)); - } - else + if (input_format == input_format_t::bjdata) { return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, u, l, m, L, M) after '#'; last byte: 0x" + last_token, "size"), nullptr)); } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType())); } /*! @@ -13867,11 +13861,12 @@ class binary_writer @brief create a binary writer @param[in] adapter output adapter to write to + @param[in] is_bjdata_ a boolean, if true, output is BJData format, default is false */ - explicit binary_writer(output_adapter_t adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)) + explicit binary_writer(output_adapter_t adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)), is_bjdata(is_bjdata_) { JSON_ASSERT(oa); - is_bjdata = is_bjdata_; + JSON_ASSERT(is_bjdata); } /*! @@ -21953,8 +21948,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } - /// @brief create a JSON value from an input in UBJSON format - /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ + /// @brief create a JSON value from an input in BJData format + /// @sa https://github.com/NeuroJSON/bjdata/blob/master/Binary_JData_Specification.md template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bjdata(InputType&& i, @@ -21985,7 +21980,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bjdata(ptr, ptr + len)) static basic_json from_bjdata(const T* ptr, std::size_t len, const bool strict = true, const bool allow_exceptions = true) @@ -21994,7 +21988,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bjdata(ptr, ptr + len)) static basic_json from_bjdata(detail::span_input_adapter&& i, const bool strict = true, const bool allow_exceptions = true) diff --git a/test/src/unit-bjdata.cpp b/test/src/unit-bjdata.cpp index f6d3dfb05..a5377b838 100644 --- a/test/src/unit-bjdata.cpp +++ b/test/src/unit-bjdata.cpp @@ -2536,6 +2536,25 @@ TEST_CASE("BJData") CHECK_THROWS_AS(_ = json::from_bjdata(v), json::parse_error&); CHECK_THROWS_WITH(_ = json::from_bjdata(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing BJData string: expected length type specification (U, i, I, u, l, m, L, M); last byte: 0x31"); } + + SECTION("parse bjdata markers in ubjson") + { + // create a single-character string for all number types + std::vector s_u = {'S', 'u', 1, 0, 'a'}; + std::vector s_m = {'S', 'm', 1, 0, 0, 0, 'a'}; + std::vector s_M = {'S', 'M', 1, 0, 0, 0, 0, 0, 0, 0, 'a'}; + + json _; + // check if string is parsed correctly to "a" + CHECK_THROWS_AS(_ = json::from_ubjson(s_u), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(s_u), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x75"); + + CHECK_THROWS_AS(_ = json::from_ubjson(s_m), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(s_m), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x6D"); + + CHECK_THROWS_AS(_ = json::from_ubjson(s_M), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(s_M), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x4D"); + } } SECTION("array") @@ -2617,6 +2636,30 @@ TEST_CASE("BJData") CHECK(json::from_bjdata(v0, true, false).is_discarded()); } + SECTION("parse bjdata markers as array size in ubjson") + { + json _; + std::vector vu = {'[', '#', 'u'}; + CHECK_THROWS_AS(_ = json::from_ubjson(vu), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(vu), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x75"); + CHECK(json::from_ubjson(vu, true, false).is_discarded()); + + std::vector vm = {'[', '#', 'm'}; + CHECK_THROWS_AS(_ = json::from_ubjson(vm), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(vm), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x6D"); + CHECK(json::from_ubjson(vm, true, false).is_discarded()); + + std::vector vM = {'[', '#', 'M'}; + CHECK_THROWS_AS(_ = json::from_ubjson(vM), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(vM), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x4D"); + CHECK(json::from_ubjson(vM, true, false).is_discarded()); + + std::vector v0 = {'[', '#', '['}; + CHECK_THROWS_AS(_ = json::from_ubjson(v0), json::parse_error&); + CHECK_THROWS_WITH(_ = json::from_ubjson(v0), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x5B"); + CHECK(json::from_ubjson(v0, true, false).is_discarded()); + } + SECTION("types") { std::vector v0 = {'[', '$'};