diff --git a/include/nlohmann/detail/view/errors.hpp b/include/nlohmann/detail/view/errors.hpp index 2b48d04b1..ff5816efd 100644 --- a/include/nlohmann/detail/view/errors.hpp +++ b/include/nlohmann/detail/view/errors.hpp @@ -55,9 +55,12 @@ template { if (f.code == error_code::input_too_large) { + // LCOV_EXCL_START (4 GiB) NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4 GiB or more is not supported by json_document", nullptr)); + // LCOV_EXCL_STOP } const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas); + // LCOV_EXCL_START (only if parse() accepts what the view rejects: a bug) static_cast(accepted); position_t pos; @@ -74,6 +77,7 @@ template } pos.chars_read_current_line = off + 1 - line_start; NLOHMANN_VIEW_THROW(parse_error::create(101, pos, "syntax error while parsing value", nullptr)); + // LCOV_EXCL_STOP } } // namespace view diff --git a/include/nlohmann/json_view.hpp b/include/nlohmann/json_view.hpp index 614f093ec..e9f37d2de 100644 --- a/include/nlohmann/json_view.hpp +++ b/include/nlohmann/json_view.hpp @@ -459,7 +459,7 @@ class basic_json_document bool ok = false; if (NLOHMANN_VIEW_UNLIKELY(size >= 0xFFFFFFF0u)) { - failure.code = detail::view::error_code::input_too_large; + failure.code = detail::view::error_code::input_too_large; // LCOV_EXCL_LINE (4 GiB) } else { diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp index fd87291d9..8dff3b47e 100644 --- a/single_include/nlohmann/json_view.hpp +++ b/single_include/nlohmann/json_view.hpp @@ -547,7 +547,8 @@ NLOHMANN_VIEW_ALWAYS_INLINE std::uint64_t parse_upto19(const unsigned char* p, u std::uint64_t w = 0; while (k >= 8) { - w = (w * 100000000u) + parse_upto8(p, 8, limit); + // (eight digits of the token: they lie below limit) + w = (w * 100000000u) + parse_eight_digits(read_eight_bytes(p)); p += 8; k -= 8; } @@ -801,10 +802,8 @@ class builder } if (c != '\\') { - if (NulIsEnd && c == 0) - { - return failed(error_code::string_missing_quote, p); - } + // (a NUL before the end of the input is a control character, as + // for json::parse, also where a NUL ends the input between values) return failed(c < 0x20 ? error_code::string_control_character : error_code::string_utf8, p); } ++p; @@ -1626,9 +1625,12 @@ template { if (f.code == error_code::input_too_large) { + // LCOV_EXCL_START (4 GiB) NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4 GiB or more is not supported by json_document", nullptr)); + // LCOV_EXCL_STOP } const BasicJsonType accepted = BasicJsonType::parse(src, src + size, nullptr, true, ignore_comments, ignore_trailing_commas); + // LCOV_EXCL_START (only if parse() accepts what the view rejects: a bug) static_cast(accepted); position_t pos; @@ -1645,6 +1647,7 @@ template } pos.chars_read_current_line = off + 1 - line_start; NLOHMANN_VIEW_THROW(parse_error::create(101, pos, "syntax error while parsing value", nullptr)); + // LCOV_EXCL_STOP } } // namespace view @@ -2483,7 +2486,7 @@ class basic_json_document bool ok = false; if (NLOHMANN_VIEW_UNLIKELY(size >= 0xFFFFFFF0u)) { - failure.code = detail::view::error_code::input_too_large; + failure.code = detail::view::error_code::input_too_large; // LCOV_EXCL_LINE (4 GiB) } else { diff --git a/tests/src/unit-json_view.cpp b/tests/src/unit-json_view.cpp index eda6db9fe..4cfe9e40a 100644 --- a/tests/src/unit-json_view.cpp +++ b/tests/src/unit-json_view.cpp @@ -351,6 +351,11 @@ TEST_CASE("json_view") CHECK(reused.memory_usage() < grown); CHECK(reused.root().materialize() == json::parse(smaller)); + // an empty document has nothing to release + json_document empty; + empty.shrink_to_fit(); + CHECK(empty.memory_usage() == 0); + // a small document stays in the storage block of the header json_document small = json_document::parse("[1,[2,3],{\"a\":\"b\\n\"}]"); // NOLINT(modernize-raw-string-literal) small.shrink_to_fit();