From: Yann Collet Date: Tue, 23 Jan 2018 21:12:40 +0000 (-0800) Subject: zstdmt : fixed ending frame with 0-size block X-Git-Tag: v1.3.4~1^2~67^2~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebd955e26a86cf5dc317126a5bbed2b5738840f5;p=thirdparty%2Fzstd.git zstdmt : fixed ending frame with 0-size block --- diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index c204fb84b..be683e83f 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -1166,7 +1166,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, { size_t const newJobThreshold = mtctx->prefixSize + mtctx->targetSectionSize; unsigned forwardInputProgress = 0; - DEBUGLOG(5, "ZSTDMT_compressStream_generic "); + DEBUGLOG(5, "ZSTDMT_compressStream_generic (endOp=%u)", (U32)endOp); assert(output->pos <= output->size); assert(input->pos <= input->size); @@ -1215,11 +1215,15 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, input->pos += toLoad; mtctx->inBuff.filled += toLoad; forwardInputProgress = toLoad>0; - } } + } + if ((input->pos < input->size) && (endOp == ZSTD_e_end)) + endOp = ZSTD_e_flush; /* can't end now : not all input consumed */ + } if ( (mtctx->jobReady) || (mtctx->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ - || ( (endOp != ZSTD_e_continue) && (mtctx->inBuff.filled > 0) ) ) { /* avoid overwriting job round buffer */ + || ((endOp != ZSTD_e_continue) && (mtctx->inBuff.filled > 0)) /* something to flush : let's go */ + || ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */ size_t const jobSize = MIN(mtctx->inBuff.filled - mtctx->prefixSize, mtctx->targetSectionSize); CHECK_F( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp==ZSTD_e_end) ); } diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 250857120..3a738c2fc 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -99,8 +99,8 @@ unsigned int FUZ_rand(unsigned int* seedPtr) if (cond) { \ DISPLAY("Error => "); \ DISPLAY(__VA_ARGS__); \ - DISPLAY(" (seed %u, test nb %u, line %u (sig %08X) \n", \ - seed, testNb, __LINE__, coreSeed); \ + DISPLAY(" (seed %u, test nb %u, line %u) \n", \ + seed, testNb, __LINE__); \ goto _output_error; \ } } @@ -1611,7 +1611,11 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double } /* mess with frame parameters */ - if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); + if (FUZ_rand(&lseed) & 1) { + U32 const checksumFlag = FUZ_rand(&lseed) & 1; + DISPLAYLEVEL(5, "t%u: frame checksum : %u \n", testNb, checksumFlag); + CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, checksumFlag, useOpaqueAPI) ); + } if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); if (FUZ_rand(&lseed) & 1) { @@ -1676,8 +1680,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double outBuff.size = outBuff.pos + dstBuffSize; CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, flush) ); - DISPLAYLEVEL(6, "t%u: compress consumed %u bytes (total : %u) \n", - testNb, (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos)); + DISPLAYLEVEL(6, "t%u: compress consumed %u bytes (total : %u) ; flush: %u (total : %u) \n", + testNb, (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos), (U32)flush, (U32)outBuff.pos); XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); @@ -1685,7 +1689,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double } /* final frame epilogue */ - { size_t remainingToFlush = (size_t)(-1); + { size_t remainingToFlush = 1; while (remainingToFlush) { ZSTD_inBuffer inBuff = { NULL, 0, 0 }; size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1); @@ -1722,8 +1726,12 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double DISPLAYLEVEL(6, "ZSTD_decompressStream input %u bytes (pos:%u/%u)\n", (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize); decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff); + if (ZSTD_isError(decompressionResult)) { + DISPLAY("ZSTD_decompressStream error : %s \n", ZSTD_getErrorName(decompressionResult)); + findDiff(copyBuffer, dstBuffer, totalTestSize); + } CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult)); - DISPLAYLEVEL(6, "inBuff.pos = %u \n", (U32)readCSrcSize); + CHECK (inBuff.pos > cSize, "ZSTD_decompressStream consumes too much input : %u > %u ", (U32)inBuff.pos, (U32)cSize); } CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize); CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (U32)inBuff.pos, (U32)cSize);