From cf81564797b26b145a72d3f47150e034c5dff147 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 12 Sep 2021 22:21:08 +0200 Subject: [PATCH] :white_check_mark: improve coverage --- .../nlohmann/detail/input/binary_reader.hpp | 24 +++++++++ single_include/nlohmann/json.hpp | 24 +++++++++ test/src/unit-bon8.cpp | 51 ++++++++++++++++++- 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 1e3f565ee..66500069f 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -2545,21 +2545,45 @@ class binary_reader { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if ((current & 0xF0) == 0xE0) { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if ((current & 0xF8) == 0xF0) { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if (current == 0xFF) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 862330ea0..467c22171 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -10839,21 +10839,45 @@ class binary_reader { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if ((current & 0xF0) == 0xE0) { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if ((current & 0xF8) == 0xF0) { result.push_back(static_cast(current)); result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } result.push_back(static_cast(get())); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bon8, "string"))) + { + return false; + } get(); } else if (current == 0xFF) diff --git a/test/src/unit-bon8.cpp b/test/src/unit-bon8.cpp index 91c8af5bf..db243e6fd 100644 --- a/test/src/unit-bon8.cpp +++ b/test/src/unit-bon8.cpp @@ -641,6 +641,39 @@ TEST_CASE("BON8") CHECK(result == expected); CHECK(json::from_bon8(result) == j); } + + SECTION("multi-byte, 2 bytes") + { + json j = "\xC2\xA3"; + std::vector expected = {0xC2, 0xA3, 0xFF}; + const auto result = json::to_bon8(j); + CHECK(result == expected); + CHECK(json::from_bon8(result) == j); + } + + SECTION("multi-byte, 3 bytes") + { + json j = "\xEF\xB8\xBB"; + std::vector expected = {0xEF, 0xB8, 0xBB, 0xFF}; + const auto result = json::to_bon8(j); + CHECK(result == expected); + CHECK(json::from_bon8(result) == j); + } + + SECTION("multi-byte, 4 bytes") + { + json j = "\xF0\x9F\x80\x84"; + std::vector expected = {0xF0, 0x9F, 0x80, 0x84, 0xFF}; + const auto result = json::to_bon8(j); + CHECK(result == expected); + CHECK(json::from_bon8(result) == j); + } + + SECTION("invalid string") + { + std::vector v = {0xF0, 0x9F, 0x80, 0x84}; + CHECK_THROWS_WITH_AS(json::from_bon8(v), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing BON8 string: unexpected end of input", json::parse_error); + } } SECTION("array") @@ -820,13 +853,20 @@ TEST_CASE("BON8") CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); } - SECTION("error in array") + SECTION("error in array with size") { std::vector v = {0x81}; SaxCountdown scp(1000); CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); } + SECTION("error in array without size") + { + std::vector v = {0x85}; + SaxCountdown scp(1000); + CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); + } + SECTION("start_object(len)") { std::vector v = {0x86}; @@ -841,11 +881,18 @@ TEST_CASE("BON8") CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); } - SECTION("error in object") + SECTION("error in object with size") { std::vector v = {0x87, 'f', 'o', 'o', 0xFF}; SaxCountdown scp(1000); CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); } + + SECTION("error in object without size") + { + std::vector v = {0x8B, 'f', 'o', 'o', 0xFF}; + SaxCountdown scp(1000); + CHECK(!json::sax_parse(v, &scp, json::input_format_t::bon8)); + } } }