]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fixed issue #62, reported by @luben
authorYann Collet <yann.collet.73@gmail.com>
Wed, 4 Nov 2015 17:19:39 +0000 (18:19 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Wed, 4 Nov 2015 17:19:39 +0000 (18:19 +0100)
lib/zstdhc.c
programs/fuzzer.c

index c061ecdbef349a2eb9f02798ecfd9ec005767440..ccd25236225152271bc2b6013cd313d3c08eada0 100644 (file)
@@ -942,45 +942,26 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr,
                                         void* dst, size_t maxDstSize,
                                   const void* src, size_t srcSize)
 {
-    static const size_t blockSize = 128 KB;
+    size_t blockSize = BLOCKSIZE;
     size_t remaining = srcSize;
     const BYTE* ip = (const BYTE*)src;
     BYTE* const ostart = (BYTE*)dst;
     BYTE* op = ostart;
-    BYTE* const oend = op + maxDstSize;
     const ZSTD_HC_blockCompressor blockCompressor = ZSTD_HC_selectBlockCompressor(ctxPtr->params.strategy);
 
-
-    while (remaining > blockSize)
+    while (remaining)
     {
-        size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, blockSize);
+        size_t cSize;
 
-        if (cSize == 0)
-        {
-            cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, blockSize);   /* block is not compressible */
-        }
-        else
-        {
-            op[0] = (BYTE)(cSize>>16);
-            op[1] = (BYTE)(cSize>>8);
-            op[2] = (BYTE)cSize;
-            op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */
-            cSize += 3;
-        }
+        if (maxDstSize < 5) return ERROR(dstSize_tooSmall);   /* not enough space to store compressed block */
 
-        remaining -= blockSize;
-        ip += blockSize;
-        op += cSize;
+        if (remaining < blockSize) blockSize = remaining;
+        cSize = blockCompressor(ctxPtr, op+3, maxDstSize-3, ip, blockSize);
         if (ZSTD_isError(cSize)) return cSize;
-    }
-
-    /* last block */
-    {
-        size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, remaining);
 
         if (cSize == 0)
         {
-            cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, remaining);   /* block is not compressible */
+            cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, blockSize);   /* block is not compressible */
         }
         else
         {
@@ -991,8 +972,10 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr,
             cSize += 3;
         }
 
+        remaining -= blockSize;
+        maxDstSize -= cSize;
+        ip += blockSize;
         op += cSize;
-        if (ZSTD_isError(cSize)) return cSize;
     }
 
     return op-ostart;
@@ -1077,7 +1060,7 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx,
 
     /* body (compression) */
     ctx->base = (const BYTE*)src;
-    op += ZSTD_HC_compress_generic (ctx, op,  maxDstSize, src, srcSize);
+    oSize = ZSTD_HC_compress_generic (ctx, op,  maxDstSize, src, srcSize);
     if(ZSTD_isError(oSize)) return oSize;
     op += oSize;
     maxDstSize -= oSize;
index a549d232f599346e99dfa9deddf50974212a07a2..217c829296b9ca202fbf25e2b5ae9a1febec7743 100644 (file)
@@ -328,14 +328,15 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
         sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
         crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0);
 
-        /* HC compression test */
-        cLevel = (FUZ_rand(&lseed) & 3) + 2;
-        cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel);
-        CHECK(ZSTD_isError(cSize), "ZSTD_compress failed");
-
         /* compression test */
+        /* covered by HC cLevel 1
         cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize);
-        CHECK(ZSTD_isError(cSize), "ZSTD_compress failed");
+        CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); */
+
+        /* HC compression test */
+        cLevel = (FUZ_rand(&lseed) & 3) +1;
+        cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel);
+        CHECK(ZSTD_isError(cSize), "ZSTD_HC_compressCCtx failed");
 
         /* compression failure test : too small dest buffer */
         if (cSize > 3)
@@ -346,16 +347,16 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
             static const U32 endMark = 0x4DC2B1A9;
             U32 endCheck;
             memcpy(dstBuffer+tooSmallSize, &endMark, 4);
-            errorCode = ZSTD_compressCCtx(ctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize);
-            CHECK(!ZSTD_isError(errorCode), "ZSTD_compress should have failed ! (buffer too small)");
+            errorCode = ZSTD_HC_compressCCtx(hcctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize, cLevel);
+            CHECK(!ZSTD_isError(errorCode), "ZSTD_HC_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize);
             memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
-            CHECK(endCheck != endMark, "ZSTD_compress : dst buffer overflow");
+            CHECK(endCheck != endMark, "ZSTD_HC_compressCCtx : dst buffer overflow");
         }
 
         /* successfull decompression tests*/
         dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
         dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize);
-        CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s)", ZSTD_getErrorName(dSize));
+        CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize);
         crcDest = XXH64(dstBuffer, sampleSize, 0);
         CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize);