From: Nick Terrell Date: Tue, 28 Apr 2020 01:10:45 +0000 (-0700) Subject: [lib] Fix single-pass mode for empty frames X-Git-Tag: v1.4.5^2~55^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f33de06c3ecdd1bce5a8f7c2b500cb2e239a1bdd;p=thirdparty%2Fzstd.git [lib] Fix single-pass mode for empty frames --- diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 9cd637354..ed82f9e01 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1660,7 +1660,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB } } /* check for single-pass mode opportunity */ - if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */ + if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN + && zds->fParams.frameType != ZSTD_skippableFrame && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart); if (cSize <= (size_t)(iend-istart)) { diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 002c16de9..31cf0a173 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -641,6 +641,32 @@ static int basicUnitTests(U32 seed, double compressibility) } DISPLAYLEVEL(3, "OK \n"); + /* Decompression single pass with empty frame */ + cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, NULL, 0, 1); + CHECK_Z(cSize); + DISPLAYLEVEL(3, "test%3i : ZSTD_decompressStream() single pass on empty frame : ", testNb++); + { ZSTD_DCtx* dctx = ZSTD_createDCtx(); + size_t const dctxSize = ZSTD_sizeof_DCtx(dctx); + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_stableOutBuffer, 1)); + + outBuff.dst = decodedBuffer; + outBuff.pos = 0; + outBuff.size = CNBufferSize; + + inBuff.src = compressedBuffer; + inBuff.size = cSize; + inBuff.pos = 0; + { size_t const r = ZSTD_decompressStream(dctx, &outBuff, &inBuff); + CHECK_Z(r); + CHECK(r != 0, "Entire frame must be decompressed"); + CHECK(outBuff.pos != 0, "Wrong size!"); + CHECK(memcmp(CNBuffer, outBuff.dst, CNBufferSize) != 0, "Corruption!"); + } + CHECK(dctxSize != ZSTD_sizeof_DCtx(dctx), "No buffers allocated"); + ZSTD_freeDCtx(dctx); + } + DISPLAYLEVEL(3, "OK \n"); + /* Decompression with ZSTD_d_stableOutBuffer */ cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, CNBuffer, CNBufferSize, 1); CHECK_Z(cSize);