diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index bcae2a5d5..0a5376646 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -3810,11 +3810,23 @@ class binary_reader // the valid range of the second byte excludes overlong forms, // surrogates, and code points above U+10FFFF - // (RFC 3629, section 4); length 0 flags the lead bytes - // 0xF5..0xF7, which BON8 can read but UTF-8 cannot encode - const auto shape = utf8_shape(static_cast(byte)); - const int continuation_bytes = (byte <= 0xDF) ? 1 : ((byte <= 0xEF) ? 2 : 3); - const bool valid_second = shape.length != 0 && second >= shape.second_lo && second <= shape.second_hi; + // (RFC 3629, section 4) + int continuation_bytes = 0; + bool valid_second = true; + if (byte <= 0xDF) + { + continuation_bytes = 1; + } + else if (byte <= 0xEF) + { + continuation_bytes = 2; + valid_second = (byte != 0xE0 || second >= 0xA0) && (byte != 0xED || second <= 0x9F); + } + else + { + continuation_bytes = 3; + valid_second = byte <= 0xF4 && (byte != 0xF0 || second >= 0x90) && (byte != 0xF4 || second <= 0x8F); + } if (JSON_HEDLEY_UNLIKELY(!valid_second)) { diff --git a/include/nlohmann/detail/string_utils.hpp b/include/nlohmann/detail/string_utils.hpp index 227c08db4..9b44623a5 100644 --- a/include/nlohmann/detail/string_utils.hpp +++ b/include/nlohmann/detail/string_utils.hpp @@ -210,8 +210,8 @@ places, which differ in speed, diagnostics, and how they read the input: bulk string scan, the bulk path of the BON8 reader, and the BON8 writer. They must accept exactly what the lexer's switch accepts. - the byte path of binary_reader::get_bon8_string(): BON8 input without bulk - access, and the bytes the bulk path leaves to it. It takes the valid range - of the second byte from utf8_shape(). + access, and the bytes the bulk path leaves to it. It keeps its own ranges: + taking them from utf8_shape() made BON8 decoding 2-3% slower (#5891). - check_utf8() in detail/view/edit.hpp: strings stored in an editable json_document, with the index of the offending byte. It also uses utf8_shape().