From: Sen Huang Date: Mon, 22 Mar 2021 21:38:21 +0000 (-0700) Subject: Add a fallback in case the total blocksize of split blocks exceeds raw block size X-Git-Tag: v1.5.0^2~75^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ef1f935b787aec0f6eab95c93538ef24e87e15a;p=thirdparty%2Fzstd.git Add a fallback in case the total blocksize of split blocks exceeds raw block size --- diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d29825c46..fe1516b79 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3327,6 +3327,7 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s seqStore_t nextSeqStore; seqStore_t currSeqStore; U32 canEmitRLEorNoCompress = 1; + const size_t dstCapacityInitial = dstCapacity; DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, @@ -3370,6 +3371,14 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s cSize += cSizeChunk; currSeqStore = nextSeqStore; } + + if (cSize > ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize) { + /* If too large, recompress the original block to avoid any chance of a single block exceeding ZSTD_BLOCKSIZE_MAX */ + cSize = ZSTD_compressSequences_singleBlock(zc, &zc->seqStore, (BYTE*)dst, dstCapacityInitial, (const BYTE*)src, blockSize, lastBlock, 1); + FORWARD_IF_ERROR(cSize, "Compressing single block from splitBlock_internal() fallback failed!"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: Compressed split block too large, recompressed"); + } + assert(cSize <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize); return cSize; }