]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
long matches support overflow
authorYann Collet <cyan@fb.com>
Tue, 29 Nov 2016 21:12:24 +0000 (13:12 -0800)
committerYann Collet <cyan@fb.com>
Tue, 29 Nov 2016 21:12:24 +0000 (13:12 -0800)
lib/decompress/zstd_decompress.c
programs/bench.c
tests/playTests.sh

index da3cf56e275f281679b245c1c7dbd5884a72ff22..6539eb41e55a4ab4fd33a16e8f5eada46e2bc4d5 100644 (file)
@@ -793,8 +793,8 @@ typedef struct {
     FSE_DState_t stateOffb;
     FSE_DState_t stateML;
     size_t prevOffset[ZSTD_REP_NUM];
-    const BYTE* ptr;
     const BYTE* base;
+    size_t pos;
     iPtrDiff gotoDict;
 } seqState_t;
 
@@ -864,15 +864,17 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState)
     if (MEM_32bits() ||
        (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
 
-    seq.match = seqState->ptr + seq.litLength - seq.offset;    /* single memory segment ! */
-    if (seq.match < seqState->base) seq.match += seqState->gotoDict;   /* what if seq.match underflows ? prefetch is a non issue, but match has now a wrong address */
+    {   size_t const pos = seqState->pos + seq.litLength;
+        seq.match = seqState->base + pos - seq.offset;    /* single memory segment */
+        if (seq.offset > pos) seq.match += seqState->gotoDict;   /* separate memory segment */
+        seqState->pos = pos + seq.matchLength;
+    }
 
     /* ANS state update */
     FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
     FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
     if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
     FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
-    seqState->ptr += seq.matchLength + seq.litLength;
 
     return seq;
 }
@@ -1042,8 +1044,8 @@ static size_t ZSTD_decompressSequencesLong(
         int seqNb;
         dctx->fseEntropy = 1;
         { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
-        seqState.ptr = op;
         seqState.base = base;
+        seqState.pos = (size_t)(op-base);
         seqState.gotoDict = (iPtrDiff)(dictEnd - base);
         CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
         FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
@@ -1194,7 +1196,7 @@ size_t ZSTD_execSequence(BYTE* op,
     if (sequence.offset > (size_t)(oLitEnd - base)) {
         /* offset beyond prefix */
         if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
-        match = dictEnd - (base-match);
+        match += (dictEnd-base);
         if (match + sequence.matchLength <= dictEnd) {
             memmove(oLitEnd, match, sequence.matchLength);
             return sequenceLength;
index df68d0adaa8b37cd4a2e3482d09548d68f72b34f..4efba160a06c12d73e4f76cd34d99b54b059cf04 100644 (file)
@@ -175,7 +175,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
     {   U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL);
         U64 const crcOrig = XXH64(srcBuffer, srcSize, 0);
         UTIL_time_t coolTime;
-        U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 100;
+        U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 1;
         U64 totalCTime=0, totalDTime=0;
         U32 cCompleted=0, dCompleted=0;
 #       define NB_MARKS 4
@@ -234,7 +234,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                 {   U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
                     if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops;
                     totalCTime += clockSpan;
-                    cCompleted = totalCTime>maxTime;
+                    cCompleted = (totalCTime >= maxTime);
             }   }
 
             cSize = 0;
@@ -279,7 +279,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                 {   U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
                     if (clockSpan < fastestD*nbLoops) fastestD = clockSpan / nbLoops;
                     totalDTime += clockSpan;
-                    dCompleted = totalDTime>maxTime;
+                    dCompleted = (totalDTime >= maxTime);
             }   }
 
             markNb = (markNb+1) % NB_MARKS;
index a50604b7e06f7a50e990b3aa3df51ee98c12cdb5..c539d567f58c23602613be4633551fe51a01bcdb 100755 (executable)
@@ -16,7 +16,7 @@ roundTripTest() {
     rm -f tmp1 tmp2
     $ECHO "roundTripTest: ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d"
     ./datagen $1 $p | $MD5SUM > tmp1
-    ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d  | $MD5SUM > tmp2
+    ./datagen $1 $p | $ZSTD --ultra -v$c | $ZSTD -d  | $MD5SUM > tmp2
     diff -q tmp1 tmp2
 }