From: Yann Collet Date: Mon, 7 May 2018 19:54:13 +0000 (-0700) Subject: fix ZSTD_compressBlock() associated with CDict X-Git-Tag: v1.3.5~3^2~63^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1122%2Fhead;p=thirdparty%2Fzstd.git fix ZSTD_compressBlock() associated with CDict reported by @let-def. It's actually a bug in ZSTD_compressBegin_usingCDict() which would pass a wrong pledgedSrcSize value (0 instead of ZSTD_CONTENTSIZE_UNKNOWN) resulting in wrong window size, resulting in downsized seqStore, resulting in segfault when writing into the seqStore later in the process. Added a test in fuzzer to cover this use case (fails before the patch). --- diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f3a49e672..08dc7db28 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2920,7 +2920,7 @@ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) { ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag); - return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0); + return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); } size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index a4feafbf2..78aa0cbad 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -204,6 +204,8 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( const BYTE* const ilimit = iend - 8; U32 offset_1=rep[0], offset_2=rep[1]; + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize); + /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls); diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 9b49ddd08..f9ea209fc 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1196,6 +1196,15 @@ static int basicUnitTests(U32 seed, double compressibility) if (r != blockSize) goto _output_error; } DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3i : Block compression with CDict : ", testNb++); + { ZSTD_CDict* const cdict = ZSTD_createCDict(CNBuffer, dictSize, 3); + if (cdict==NULL) goto _output_error; + CHECK( ZSTD_compressBegin_usingCDict(cctx, cdict) ); + CHECK( ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize) ); + ZSTD_freeCDict(cdict); + } + DISPLAYLEVEL(3, "OK \n"); + ZSTD_freeCCtx(cctx); } ZSTD_freeDCtx(dctx);