]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
[lib] Fix single-pass mode for empty frames
authorNick Terrell <terrelln@fb.com>
Tue, 28 Apr 2020 01:10:45 +0000 (18:10 -0700)
committerNick Terrell <terrelln@fb.com>
Tue, 28 Apr 2020 03:04:01 +0000 (20:04 -0700)
lib/decompress/zstd_decompress.c
tests/zstreamtest.c

index 9cd637354acd9302f2c2c73d6a4f98859d14a33d..ed82f9e010ff1b6e40bdf21344571eb48bf45890 100644 (file)
@@ -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)) {
index 002c16de95746ad328f751adbaff06834e6e98ac..31cf0a1732213b8adee8c851f6804f96171de34f 100644 (file)
@@ -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);