diff --git a/port/port_stdcxx.h b/port/port_stdcxx.h index 6f503f695b..c8e8345f40 100644 --- a/port/port_stdcxx.h +++ b/port/port_stdcxx.h @@ -164,7 +164,9 @@ inline bool Zstd_GetUncompressedLength(const char* input, size_t length, size_t* result) { #if HAVE_ZSTD size_t size = ZSTD_getFrameContentSize(input, length); - if (size == 0) return false; + if (size == 0 || size == ZSTD_CONTENTSIZE_UNKNOWN || + size == ZSTD_CONTENTSIZE_ERROR) + return false; *result = size; return true; #else diff --git a/table/block.cc b/table/block.cc index 3b1525770b..742ced8307 100644 --- a/table/block.cc +++ b/table/block.cc @@ -68,7 +68,8 @@ static inline const char* DecodeEntry(const char* p, const char* limit, if ((p = GetVarint32Ptr(p, limit, value_length)) == nullptr) return nullptr; } - if (static_cast(limit - p) < (*non_shared + *value_length)) { + if (static_cast(limit - p) < *non_shared || + static_cast(limit - p) - *non_shared < *value_length) { return nullptr; } return p; diff --git a/table/format.cc b/table/format.cc index ae998c1f30..d3eb4d9f4c 100644 --- a/table/format.cc +++ b/table/format.cc @@ -4,6 +4,8 @@ #include "table/format.h" +#include + #include "leveldb/env.h" #include "leveldb/options.h" #include "port/port.h" @@ -74,6 +76,11 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options, // Read the block contents as well as the type/crc footer. // See table_builder.cc for the code that built this structure. + if (handle.size() > + static_cast(std::numeric_limits::max()) - + kBlockTrailerSize) { + return Status::Corruption("block size overflow"); + } size_t n = static_cast(handle.size()); char* buf = new char[n + kBlockTrailerSize]; Slice contents;