diff --git a/src/ripple/basics/CompressionAlgorithms.h b/src/ripple/basics/CompressionAlgorithms.h index 5be6e923c..eef260891 100644 --- a/src/ripple/basics/CompressionAlgorithms.h +++ b/src/ripple/basics/CompressionAlgorithms.h @@ -65,26 +65,33 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf) /** * @param in Compressed data - * @param inSize Size of compressed data + * @param inSizeUnchecked Size of compressed data * @param decompressed Buffer to hold decompressed data - * @param decompressedSize Size of the decompressed buffer + * @param decompressedSizeUnchecked Size of the decompressed buffer * @return size of the decompressed data */ inline std::size_t lz4Decompress( std::uint8_t const* in, - std::size_t inSize, + std::size_t inSizeUnchecked, std::uint8_t* decompressed, - std::size_t decompressedSize) + std::size_t decompressedSizeUnchecked) { - auto ret = LZ4_decompress_safe( - reinterpret_cast(in), - reinterpret_cast(decompressed), - inSize, - decompressedSize); + int const inSize = static_cast(inSizeUnchecked); + int const decompressedSize = static_cast(decompressedSizeUnchecked); - if (ret <= 0 || ret != decompressedSize) - Throw("lz4 decompress: failed"); + if (inSize <= 0) + Throw("lz4Decompress: integer overflow (input)"); + + if (decompressedSize <= 0) + Throw("lz4Decompress: integer overflow (output)"); + + if (LZ4_decompress_safe( + reinterpret_cast(in), + reinterpret_cast(decompressed), + inSize, + decompressedSize) != decompressedSize) + Throw("lz4Decompress: failed"); return decompressedSize; } diff --git a/src/ripple/nodestore/impl/codec.h b/src/ripple/nodestore/impl/codec.h index 21c68ff58..a6749e0d1 100644 --- a/src/ripple/nodestore/impl/codec.h +++ b/src/ripple/nodestore/impl/codec.h @@ -42,22 +42,30 @@ template std::pair lz4_decompress(void const* in, std::size_t in_size, BufferFactory&& bf) { - using std::runtime_error; - using namespace nudb::detail; - std::pair result; - std::uint8_t const* p = reinterpret_cast(in); - auto const n = read_varint(p, in_size, result.second); - if (n == 0) - Throw("lz4 decompress: n == 0"); - void* const out = bf(result.second); - result.first = out; + if (static_cast(in_size) < 0) + Throw("lz4_decompress: integer overflow (input)"); + + std::size_t outSize = 0; + + auto const n = read_varint( + reinterpret_cast(in), in_size, outSize); + + if (n == 0 || n >= in_size) + Throw("lz4_decompress: invalid blob"); + + if (static_cast(outSize) <= 0) + Throw("lz4_decompress: integer overflow (output)"); + + void* const out = bf(outSize); + if (LZ4_decompress_safe( reinterpret_cast(in) + n, reinterpret_cast(out), - in_size - n, - result.second) != result.second) - Throw("lz4 decompress: LZ4_decompress_safe"); - return result; + static_cast(in_size - n), + static_cast(outSize)) != static_cast(outSize)) + Throw("lz4_decompress: LZ4_decompress_safe"); + + return {out, outSize}; } template