From: Yann Collet Date: Tue, 29 Nov 2016 21:12:24 +0000 (-0800) Subject: long matches support overflow X-Git-Tag: v1.1.2~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f5350f610a93817554bf402946ae9203a6ca7b7;p=thirdparty%2Fzstd.git long matches support overflow --- diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index da3cf56e2..6539eb41e 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -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; irep[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; diff --git a/programs/bench.c b/programs/bench.c index df68d0ada..4efba160a 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -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; diff --git a/tests/playTests.sh b/tests/playTests.sh index a50604b7e..c539d567f 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -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 }