]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
fixed : frame concatenation without checksum
authorYann Collet <yann.collet.73@gmail.com>
Thu, 28 Jul 2016 18:30:25 +0000 (20:30 +0200)
committerYann Collet <yann.collet.73@gmail.com>
Thu, 28 Jul 2016 18:30:25 +0000 (20:30 +0200)
lib/decompress/zbuff_decompress.c
lib/decompress/zstd_decompress.c
lib/zstd.h
programs/playTests.sh

index b22bd84a6776fa43a11b4d95369a10e8e9b55986..908120fc7ffd8ff6a8e8261da79f13a5a31d4be5 100644 (file)
@@ -282,7 +282,7 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
     *dstCapacityPtr = op-ostart;
     {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
         if (!nextSrcSizeHint) return (zbd->outEnd != zbd->outStart);   /* return 0 only if fully flushed too */
-        if (nextSrcSizeHint > 4) nextSrcSizeHint += ZSTD_blockHeaderSize;
+        nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zbd->zd) == ZSTDnit_block);
         if (zbd->inPos > nextSrcSizeHint) return ERROR(GENERIC);   /* should never happen */
         nextSrcSizeHint -= zbd->inPos;   /* already loaded*/
         return nextSrcSizeHint;
index 5aa43790ac3a97f6306b74f49ad7a6b7579a76c0..972a8143d43c5ddd6fa52cb1f9757493f4ab359e 100644 (file)
@@ -984,6 +984,27 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
 ************************************/
 size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
 
+ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
+    switch(dctx->stage)
+    {
+    default:   /* should not happen */
+    case ZSTDds_getFrameHeaderSize:
+    case ZSTDds_decodeFrameHeader:
+        return ZSTDnit_frameHeader;
+    case ZSTDds_decodeBlockHeader:
+        return ZSTDnit_blockHeader;
+    case ZSTDds_decompressBlock:
+        return ZSTDnit_block;
+    case ZSTDds_decompressLastBlock:
+        return ZSTDnit_lastBlock;
+    case ZSTDds_checkChecksum:
+        return ZSTDnit_checksum;
+    case ZSTDds_decodeSkippableHeader:
+    case ZSTDds_skipFrame:
+        return ZSTDnit_skippableFrame;
+    }
+}
+
 int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }   /* for zbuff */
 
 /** ZSTD_decompressContinue() :
index 01ac7d268d94af9125b39d148eaa8f03cbc14c23..46338aeac6636e5929cc053be78789ae4e33fdd2 100644 (file)
@@ -370,6 +370,9 @@ ZSTDLIB_API void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx)
 ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
 ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 
+typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
+ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+
 /*
   Buffer-less streaming decompression (synchronous mode)
 
@@ -408,6 +411,8 @@ ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t ds
   A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
   Context can then be reset to start a new decompression.
 
+  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
+  But this information is not required to properly decode a frame.
 
   == Special case : skippable frames ==
 
index 05eb49fceee56f5b2f4711ed5e755923d2ac69dd..1fc508f9dd398bc4db66eb09e8017c56aa97774f 100755 (executable)
@@ -96,6 +96,13 @@ cat hello.zstd world.zstd > helloworld.zstd
 $ZSTD -dc helloworld.zstd > result.tmp
 cat result.tmp
 sdiff helloworld.tmp result.tmp
+$ECHO "frame concatenation without checksum"
+$ZSTD -c hello.tmp > hello.zstd --no-check
+$ZSTD -c world.tmp > world.zstd --no-check
+cat hello.zstd world.zstd > helloworld.zstd
+$ZSTD -dc helloworld.zstd > result.tmp
+cat result.tmp
+sdiff helloworld.tmp result.tmp
 rm ./*.tmp ./*.zstd
 $ECHO "frame concatenation tests completed"