Skip to content

Commit b4467c1

Browse files
committed
Fix bufferless API with attached dictionary
Fixes #3102.
1 parent 3291691 commit b4467c1

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

lib/compress/zstd_compress_internal.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1172,10 +1172,15 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
11721172
(unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
11731173
assert(blockEndIdx >= loadedDictEnd);
11741174

1175-
if (blockEndIdx > loadedDictEnd + maxDist) {
1175+
if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) {
11761176
/* On reaching window size, dictionaries are invalidated.
11771177
* For simplification, if window size is reached anywhere within next block,
11781178
* the dictionary is invalidated for the full block.
1179+
*
1180+
* We also have to invalidate the dictionary if ZSTD_window_update() has detected
1181+
* non-contiguous segments, which means that loadedDictEnd != window->dictLimit.
1182+
* loadedDictEnd may be 0, if forceWindow is true, but in that case we never use
1183+
* dictMatchState, so setting it to NULL is not a problem.
11791184
*/
11801185
DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)");
11811186
*loadedDictEndPtr = 0;

tests/fuzzer.c

+21
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,27 @@ static int basicUnitTests(U32 const seed, double compressibility)
25922592
}
25932593
DISPLAYLEVEL(3, "OK \n");
25942594

2595+
DISPLAYLEVEL(3, "test%3d : bufferless api with cdict : ", testNb++);
2596+
{ ZSTD_CDict* const cdict = ZSTD_createCDict(dictBuffer, dictSize, 1);
2597+
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
2598+
ZSTD_frameParameters const fParams = { 0, 1, 0 };
2599+
size_t cBlockSize;
2600+
cSize = 0;
2601+
CHECK_Z(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN));
2602+
cBlockSize = ZSTD_compressContinue(cctx, (char*)compressedBuffer + cSize, compressedBufferSize - cSize, CNBuffer, 1000);
2603+
CHECK_Z(cBlockSize);
2604+
cSize += cBlockSize;
2605+
cBlockSize = ZSTD_compressEnd(cctx, (char*)compressedBuffer + cSize, compressedBufferSize - cSize, (char const*)CNBuffer + 2000, 1000);
2606+
CHECK_Z(cBlockSize);
2607+
cSize += cBlockSize;
2608+
2609+
CHECK_Z(ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, dictBuffer, dictSize));
2610+
2611+
ZSTD_freeCDict(cdict);
2612+
ZSTD_freeDCtx(dctx);
2613+
}
2614+
DISPLAYLEVEL(3, "OK \n");
2615+
25952616
DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dct_fullDict on a good dictionary : ", testNb++);
25962617
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
25972618
ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem);

0 commit comments

Comments
 (0)