From: Yann Collet Date: Tue, 29 Nov 2016 03:59:11 +0000 (-0800) Subject: long decoder compatible with round and separate buffers X-Git-Tag: v1.1.2~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52e136ed3d174d134500fbf679bec9ddcbdff490;p=thirdparty%2Fzstd.git long decoder compatible with round and separate buffers --- diff --git a/lib/common/mem.h b/lib/common/mem.h index 681dd35d2..32c63dd17 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -55,14 +55,16 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size typedef int32_t S32; typedef uint64_t U64; typedef int64_t S64; + typedef intptr_t iPtrDiff; #else - typedef unsigned char BYTE; + typedef unsigned char BYTE; typedef unsigned short U16; typedef signed short S16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; typedef signed long long S64; + typedef ptrdiff_t iPtrDiff; #endif diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 2d4087335..da3cf56e2 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -794,6 +794,8 @@ typedef struct { FSE_DState_t stateML; size_t prevOffset[ZSTD_REP_NUM]; const BYTE* ptr; + const BYTE* base; + iPtrDiff gotoDict; } seqState_t; @@ -862,7 +864,8 @@ 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; /* only for single memory segment ! */ + 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 */ /* ANS state update */ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ @@ -954,7 +957,6 @@ size_t ZSTD_execSequenceLong(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); if (match + sequence.matchLength <= dictEnd) { memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; @@ -1041,6 +1043,8 @@ static size_t ZSTD_decompressSequencesLong( dctx->fseEntropy = 1; { U32 i; for (i=0; irep[i]; } seqState.ptr = op; + seqState.base = 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); FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);