diff --git a/src/json.hpp b/src/json.hpp index 23058bee..1d92b51a 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6831,6 +6831,27 @@ class basic_json } } + /*! + @brief checks if a given length does not exceed the size of a given vector + + To secure the access to the byte vector during CBOR/MessagePack + deserialization, bytes are copied from the vector into buffers. This + function checks if the number of bytes to copy (@a len) does not exceed the + size of the given vector @a vec. + + @param[in] vec byte vector + @param[in] len length + + @throws out_of_range if `len > v.size()` + */ + static void check_length(const std::vector& vec, const size_t& len) + { + if (len > vec.size()) + { + throw std::out_of_range("len out of range"); + } + } + /*! @brief create a JSON value from a given MessagePack vector @@ -6882,6 +6903,7 @@ class basic_json const size_t len = v[current_idx] & 0x1f; const size_t offset = current_idx + 1; idx += len; // skip content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } } @@ -6985,6 +7007,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 2; idx += len + 1; // skip size byte + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -6993,6 +7016,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 3; idx += len + 2; // skip 2 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7001,6 +7025,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 5; idx += len + 4; // skip 4 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7219,6 +7244,7 @@ class basic_json const auto len = static_cast(v[current_idx] - 0x60); const size_t offset = current_idx + 1; idx += len; // skip content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7227,6 +7253,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 2; idx += len + 1; // skip size byte + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7235,6 +7262,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 3; idx += len + 2; // skip 2 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7243,6 +7271,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 5; idx += len + 4; // skip 4 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7251,6 +7280,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 9; idx += len + 8; // skip 8 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index ac9a3315..d5b05c01 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -6831,6 +6831,27 @@ class basic_json } } + /*! + @brief checks if a given length does not exceed the size of a given vector + + To secure the access to the byte vector during CBOR/MessagePack + deserialization, bytes are copied from the vector into buffers. This + function checks if the number of bytes to copy (@a len) does not exceed the + size of the given vector @a vec. + + @param[in] vec byte vector + @param[in] len length + + @throws out_of_range if `len > v.size()` + */ + static void check_length(const std::vector& vec, const size_t& len) + { + if (len > vec.size()) + { + throw std::out_of_range("len out of range"); + } + } + /*! @brief create a JSON value from a given MessagePack vector @@ -6882,6 +6903,7 @@ class basic_json const size_t len = v[current_idx] & 0x1f; const size_t offset = current_idx + 1; idx += len; // skip content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } } @@ -6985,6 +7007,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 2; idx += len + 1; // skip size byte + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -6993,6 +7016,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 3; idx += len + 2; // skip 2 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7001,6 +7025,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 5; idx += len + 4; // skip 4 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7219,6 +7244,7 @@ class basic_json const auto len = static_cast(v[current_idx] - 0x60); const size_t offset = current_idx + 1; idx += len; // skip content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7227,6 +7253,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 2; idx += len + 1; // skip size byte + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7235,6 +7262,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 3; idx += len + 2; // skip 2 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7243,6 +7271,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 5; idx += len + 4; // skip 4 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); } @@ -7251,6 +7280,7 @@ class basic_json const auto len = static_cast(get_from_vector(v, current_idx)); const size_t offset = current_idx + 9; idx += len + 8; // skip 8 size bytes + content bytes + check_length(v, len + offset); return std::string(reinterpret_cast(v.data()) + offset, len); }