From: Yann Collet Date: Wed, 4 Nov 2015 17:19:39 +0000 (+0100) Subject: Fixed issue #62, reported by @luben X-Git-Tag: zstd-0.3.3^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e3582719c3fdc2be5792ebdf9304d7a65fcabec;p=thirdparty%2Fzstd.git Fixed issue #62, reported by @luben --- diff --git a/lib/zstdhc.c b/lib/zstdhc.c index c061ecdbe..ccd252362 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -942,45 +942,26 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr, void* dst, size_t maxDstSize, const void* src, size_t srcSize) { - static const size_t blockSize = 128 KB; + size_t blockSize = BLOCKSIZE; size_t remaining = srcSize; const BYTE* ip = (const BYTE*)src; BYTE* const ostart = (BYTE*)dst; BYTE* op = ostart; - BYTE* const oend = op + maxDstSize; const ZSTD_HC_blockCompressor blockCompressor = ZSTD_HC_selectBlockCompressor(ctxPtr->params.strategy); - - while (remaining > blockSize) + while (remaining) { - size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, blockSize); + size_t cSize; - if (cSize == 0) - { - cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, blockSize); /* block is not compressible */ - } - else - { - op[0] = (BYTE)(cSize>>16); - op[1] = (BYTE)(cSize>>8); - op[2] = (BYTE)cSize; - op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */ - cSize += 3; - } + if (maxDstSize < 5) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */ - remaining -= blockSize; - ip += blockSize; - op += cSize; + if (remaining < blockSize) blockSize = remaining; + cSize = blockCompressor(ctxPtr, op+3, maxDstSize-3, ip, blockSize); if (ZSTD_isError(cSize)) return cSize; - } - - /* last block */ - { - size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, remaining); if (cSize == 0) { - cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, remaining); /* block is not compressible */ + cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, blockSize); /* block is not compressible */ } else { @@ -991,8 +972,10 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr, cSize += 3; } + remaining -= blockSize; + maxDstSize -= cSize; + ip += blockSize; op += cSize; - if (ZSTD_isError(cSize)) return cSize; } return op-ostart; @@ -1077,7 +1060,7 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx, /* body (compression) */ ctx->base = (const BYTE*)src; - op += ZSTD_HC_compress_generic (ctx, op, maxDstSize, src, srcSize); + oSize = ZSTD_HC_compress_generic (ctx, op, maxDstSize, src, srcSize); if(ZSTD_isError(oSize)) return oSize; op += oSize; maxDstSize -= oSize; diff --git a/programs/fuzzer.c b/programs/fuzzer.c index a549d232f..217c82929 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -328,14 +328,15 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize); crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0); - /* HC compression test */ - cLevel = (FUZ_rand(&lseed) & 3) + 2; - cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel); - CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); - /* compression test */ + /* covered by HC cLevel 1 cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize); - CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); + CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); */ + + /* HC compression test */ + cLevel = (FUZ_rand(&lseed) & 3) +1; + cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel); + CHECK(ZSTD_isError(cSize), "ZSTD_HC_compressCCtx failed"); /* compression failure test : too small dest buffer */ if (cSize > 3) @@ -346,16 +347,16 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit static const U32 endMark = 0x4DC2B1A9; U32 endCheck; memcpy(dstBuffer+tooSmallSize, &endMark, 4); - errorCode = ZSTD_compressCCtx(ctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize); - CHECK(!ZSTD_isError(errorCode), "ZSTD_compress should have failed ! (buffer too small)"); + errorCode = ZSTD_HC_compressCCtx(hcctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize, cLevel); + CHECK(!ZSTD_isError(errorCode), "ZSTD_HC_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize); memcpy(&endCheck, dstBuffer+tooSmallSize, 4); - CHECK(endCheck != endMark, "ZSTD_compress : dst buffer overflow"); + CHECK(endCheck != endMark, "ZSTD_HC_compressCCtx : dst buffer overflow"); } /* successfull decompression tests*/ dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1; dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize); - CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s)", ZSTD_getErrorName(dSize)); + CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize); crcDest = XXH64(dstBuffer, sampleSize, 0); CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize);