From: Nick Terrell Date: Thu, 12 Apr 2018 23:02:03 +0000 (-0700) Subject: Enforce pledgeSrcSize whenever known (#1106) X-Git-Tag: v1.3.5~3^2~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c3f59e68f1771dabeb020c0aa0f30b8c9c59936;p=thirdparty%2Fzstd.git Enforce pledgeSrcSize whenever known (#1106) The test fails before the patch and passes after. Fixes #1095. --- diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 13ac747c5..590e92c8e 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2152,6 +2152,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); size_t pos=0; + assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)); if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall); DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", !params.fParams.noDictIDFlag, dictID, dictIDSizeCode); @@ -2245,7 +2246,9 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, if (ZSTD_isError(cSize)) return cSize; cctx->consumedSrcSize += srcSize; cctx->producedCSize += (cSize + fhSize); - if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) { DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u", (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); @@ -2608,7 +2611,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, if (ZSTD_isError(cSize)) return cSize; endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); if (ZSTD_isError(endResult)) return endResult; - if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); DEBUGLOG(4, "end of frame : controlling src size"); if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) { DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u", diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index b94f282f5..14412f4b9 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -460,6 +460,21 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); } + DISPLAYLEVEL(3, "test%3i : wrong srcSize !contentSizeFlag : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); + { ZSTD_parameters params = ZSTD_getParams(1, CNBufferSize, 0); + params.fParams.contentSizeFlag = 0; + CHECK_Z(ZSTD_initCStream_advanced(zc, NULL, 0, params, CNBufferSize - MIN(CNBufferSize, 200 KB))); + outBuff.dst = (char*)compressedBuffer; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = CNBufferSize; + inBuff.pos = 0; + { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); + if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; /* must fail : wrong srcSize */ + DISPLAYLEVEL(3, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); + } } + /* Complex context re-use scenario */ DISPLAYLEVEL(3, "test%3i : context re-use : ", testNb++); ZSTD_freeCStream(zc);