diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 4041cedba..240ad9765 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -1788,20 +1788,361 @@ class binary_reader return false; } - string_t key; for (std::size_t i = 0; i < len; ++i) { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) + switch (get()) { - return false; + // EOF + case std::char_traits::eof(): + return unexpect_eof(input_format_t::msgpack, "value"); + + // positive fixint + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + { + if( JSON_HEDLEY_UNLIKELY( ! sax->key_unsiged(static_cast(current) ) ) ){ + return false; + } + break; + } + + // fixstr + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + case 0xD9: // str 8 + case 0xDA: // str 16 + case 0xDB: // str 32 + { + string_t s; + if( JSON_HEDLEY_UNLIKELY( ! ( get_msgpack_string(s) && sax->key(s) ) ) ){ + return false; + } + break; + } + + case 0xC0: // nil + { + if( JSON_HEDLEY_UNLIKELY( ! sax->key_null() ) ){ + return false; + } + break; + } + + case 0xC2: // false + { + if( JSON_HEDLEY_UNLIKELY( ! sax->key_boolean(false) ) ){ + return false; + } + break; + } + + case 0xC3: // true + { + if( JSON_HEDLEY_UNLIKELY( ! sax->key_boolean(true) ) ){ + return false; + } + break; + } + + case 0xCA: // float 32 + { + float number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast(number), "") ) ) ){ + return false; + } + break; + } + + case 0xCB: // float 64 + { + double number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast(number), "") ) ) ){ + return false; + } + break; + } + + case 0xCC: // uint 8 + { + std::uint8_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ){ + return false; + } + break; + } + + case 0xCD: // uint 16 + { + std::uint16_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ){ + return false; + } + break; + } + + case 0xCE: // uint 32 + { + std::uint32_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ){ + return false; + } + break; + } + + case 0xCF: // uint 64 + { + std::uint64_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ){ + return false; + } + break; + } + + case 0xD0: // int 8 + { + std::int8_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ){ + return false; + } + break; + } + + case 0xD1: // int 16 + { + std::int16_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ){ + return false; + } + break; + } + + case 0xD2: // int 32 + { + std::int32_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ){ + return false; + } + break; + } + + case 0xD3: // int 64 + { + std::int64_t number{}; + if( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ){ + return false; + } + break; + } + + // negative fixint + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + { + if( JSON_HEDLEY_UNLIKELY( ! sax->key_integer(static_cast(current)) ) ){ + return false; + } + break; + } + + default: // anything else + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } } if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) { return false; } - key.clear(); + } return sax->end_object(); diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index 406008167..1e2fc612c 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -96,6 +96,46 @@ struct json_sax */ virtual bool key(string_t& val) = 0; + /*! + @brief an object key of null value was read + @return whether parsing should proceed + */ + virtual bool key_null() { + return false; + } + + /*! + @brief an object key of type bool was read + @return whether parsing should proceed + */ + virtual bool key_boolean(bool val) { + return false; + } + + /*! + @brief an object key of type integer number was read + @return whether parsing should proceed + */ + virtual bool key_integer(number_integer_t val) { + return false; + } + + /*! + @brief an object key of type unsigned was read + @return whether parsing should proceed + */ + virtual bool key_unsigned(number_unsigned_t val) { + return false; + } + + /*! + @brief an object key of type float was read + @return whether parsing should proceed + */ + virtual bool key_float(number_float_t val, const string_t& s) { + return false; + } + /*! @brief the end of an object was read @return whether parsing should proceed