From 298d24fa573842c7cc0c3530869817bc9ebe36f8 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 21 May 2018 20:12:11 -0400 Subject: [PATCH] Make loadedDictEnd an Index, not the Dict Len --- lib/compress/zstd_compress.c | 4 +++- lib/compress/zstd_compress_internal.h | 6 ++++++ lib/compress/zstd_fast.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e49046fc..105cea44 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1209,6 +1209,8 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, * in-place. We decide here which strategy to use. */ const int attachDict = ( pledgedSrcSize <= 8 KB || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN ) + && !params.forceWindow /* dictMatchState isn't correctly + * handled in _enforceMaxDist */ && cdict->cParams.strategy == ZSTD_fast && ZSTD_equivalentCParams(cctx->appliedParams.cParams, cdict->cParams); @@ -1244,7 +1246,7 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, cctx->blockState.matchState.window.base + cdictLen; ZSTD_window_clear(&cctx->blockState.matchState.window); } - cctx->blockState.matchState.loadedDictEnd = params.forceWindow ? 0 : cdictLen; + cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit; } } else { DEBUGLOG(4, "copying dictionary into context"); diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index a61fc374..a7666d5c 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -594,14 +594,20 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, * ZSTD_window_enforceMaxDist(): * Updates lowLimit so that: * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd + * * This allows a simple check that index >= lowLimit to see if index is valid. * This must be called before a block compression call, with srcEnd as the block * source end. + * * If loadedDictEndPtr is not NULL, we set it to zero once we update lowLimit. * This is because dictionaries are allowed to be referenced as long as the last * byte of the dictionary is in the window, but once they are out of range, * they cannot be referenced. If loadedDictEndPtr is NULL, we use * loadedDictEnd == 0. + * + * In normal dict mode, the dict is between lowLimit and dictLimit. In + * dictMatchState mode, lowLimit and dictLimit are the same, and the dictionary + * is below them. forceWindow and dictMatchState are therefore incompatible. */ MEM_STATIC void ZSTD_window_enforceMaxDist(ZSTD_window_t* window, void const* srcEnd, U32 maxDist, diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 3bac2bdd..bf962a17 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -72,7 +72,7 @@ size_t ZSTD_compressBlock_fast_generic( const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL; const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ? - prefixLowestIndex - (U32)(dictEnd - dictBase) : + ms->loadedDictEnd - (U32)(dictEnd - dictBase) : 0; const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictLowest);