diff --git a/src/json.hpp b/src/json.hpp index 486b9c6c18..9c27fb07f2 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8814,7 +8814,7 @@ class basic_json // store number of bytes in the buffer fill_size = static_cast(is.gcount()); - // skip byte-order mark + // skip byte order mark if (fill_size >= 3 and buffer[0] == '\xEF' and buffer[1] == '\xBB' and buffer[2] == '\xBF') { buffer_pos += 3; @@ -8911,7 +8911,13 @@ class basic_json public: input_buffer_adapter(const char* b, size_t l) : input_adapter(), cursor(b), limit(b + l), start(b) - {} + { + // skip byte order mark + if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') + { + cursor += 3; + } + } // delete because of pointer members input_buffer_adapter(const input_buffer_adapter&) = delete; diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 19fa686eb4..ec8ba6ad66 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1169,4 +1169,10 @@ TEST_CASE("regression tests") std::vector vec = {'"', '\\', '"', 'X', '"', '"'}; CHECK_THROWS_AS(json::parse(vec), json::parse_error); } + + SECTION("issue #602 - BOM not skipped when using json:parse(iterator)") + { + std::string i = "\xef\xbb\xbf{\n \"foo\": true\n}"; + CHECK_NOTHROW(json::parse(i.begin(), i.end())); + } } diff --git a/test/src/unit-unicode.cpp b/test/src/unit-unicode.cpp index 17cd9aac29..e55a7573f2 100644 --- a/test/src/unit-unicode.cpp +++ b/test/src/unit-unicode.cpp @@ -1012,10 +1012,19 @@ TEST_CASE("Unicode", "[hide]") SECTION("ignore byte-order-mark") { - // read a file with a UTF-8 BOM - std::ifstream f("test/data/json_nlohmann_tests/bom.json"); - json j; - CHECK_NOTHROW(f >> j); + SECTION("in a stream") + { + // read a file with a UTF-8 BOM + std::ifstream f("test/data/json_nlohmann_tests/bom.json"); + json j; + CHECK_NOTHROW(f >> j); + } + + SECTION("with an iterator") + { + std::string i = "\xef\xbb\xbf{\n \"foo\": true\n}"; + CHECK_NOTHROW(json::parse(i.begin(), i.end())); + } } SECTION("error for incomplete/wrong BOM")