From 82f1c1418b2d357653698e6fd9362ca663b1ff28 Mon Sep 17 00:00:00 2001 From: "jingkai.yuan" Date: Wed, 2 Mar 2022 16:35:21 -0800 Subject: [PATCH] Fix corruption error when compressing blob data with zlib. (#9572) Summary: The plain data length may not be big enough if the compression actually expands data. So use deflateBound() to get the upper limit on the compressed output before deflate(). Pull Request resolved: https://github.com/facebook/rocksdb/pull/9572 Reviewed By: riversand963 Differential Revision: D34326475 Pulled By: ajkr fbshipit-source-id: 4b679cb7a83a62782a127785b4d5eb9aa4646449 --- util/compression.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/util/compression.h b/util/compression.h index a58b2b575..b28c76f0d 100644 --- a/util/compression.h +++ b/util/compression.h @@ -724,9 +724,6 @@ inline bool Zlib_Compress(const CompressionInfo& info, output_header_len = compression::PutDecompressedSizeInfo( output, static_cast(length)); } - // Resize output to be the plain data length. - // This may not be big enough if the compression actually expands data. - output->resize(output_header_len + length); // The memLevel parameter specifies how much memory should be allocated for // the internal compression state. @@ -760,12 +757,16 @@ inline bool Zlib_Compress(const CompressionInfo& info, } } + // Get an upper bound on the compressed size. + size_t upper_bound = deflateBound(&_stream, length); + output->resize(output_header_len + upper_bound); + // Compress the input, and put compressed data in output. _stream.next_in = (Bytef*)input; _stream.avail_in = static_cast(length); // Initialize the output size. - _stream.avail_out = static_cast(length); + _stream.avail_out = static_cast(upper_bound); _stream.next_out = reinterpret_cast(&(*output)[output_header_len]); bool compressed = false;