diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 5dec85888..14918cb42 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -658,7 +658,19 @@ static size_t ZSTD_decompressSequences( } -size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, +static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) +{ + if (dst != dctx->previousDstEnd) /* not contiguous */ + { + dctx->dictEnd = dctx->previousDstEnd; + dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); + dctx->base = dst; + dctx->previousDstEnd = dst; + } +} + + +static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize) { @@ -675,6 +687,15 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, } +size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* src, size_t srcSize) +{ + ZSTD_checkContinuity(dctx, dst); + return ZSTD_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize); +} + + size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, @@ -735,7 +756,7 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx, switch(blockProperties.blockType) { case bt_compressed: - decodedSize = ZSTD_decompressBlock(ctx, op, oend-op, ip, cBlockSize); + decodedSize = ZSTD_decompressBlock_internal(ctx, op, oend-op, ip, cBlockSize); break; case bt_raw : decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize); @@ -786,13 +807,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con { /* Sanity check */ if (srcSize != ctx->expected) return ERROR(srcSize_wrong); - if (dst != ctx->previousDstEnd) /* not contiguous */ - { - ctx->dictEnd = ctx->previousDstEnd; - ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base)); - ctx->base = dst; - ctx->previousDstEnd = dst; - } + ZSTD_checkContinuity(ctx, dst); /* Decompress : frame header; part 1 */ switch (ctx->stage) @@ -849,7 +864,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con switch(ctx->bType) { case bt_compressed: - rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize); + rSize = ZSTD_decompressBlock_internal(ctx, dst, maxDstSize, src, srcSize); break; case bt_raw : rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize); @@ -874,10 +889,10 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con } -void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* src, size_t srcSize) +void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* dict, size_t dictSize) { ctx->dictEnd = ctx->previousDstEnd; - ctx->vBase = (const char*)src - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base)); - ctx->base = src; - ctx->previousDstEnd = (const char*)src + srcSize; + ctx->vBase = (const char*)dict - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base)); + ctx->base = dict; + ctx->previousDstEnd = (const char*)dict + dictSize; } diff --git a/programs/fuzzer.c b/programs/fuzzer.c index 28f50c54a..9c427c206 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -273,6 +273,7 @@ static int basicUnitTests(U32 seed, double compressibility) ZSTD_CCtx* const cctx = ZSTD_createCCtx(); ZSTD_DCtx* const dctx = ZSTD_createDCtx(); const size_t blockSize = 100 KB; + const size_t dictSize = 16 KB; /* basic block compression */ DISPLAYLEVEL(4, "test%3i : Block compression test : ", testNb++); @@ -290,6 +291,25 @@ static int basicUnitTests(U32 seed, double compressibility) if (result != blockSize) goto _output_error; DISPLAYLEVEL(4, "OK \n"); + /* dictionary block compression */ + DISPLAYLEVEL(4, "test%3i : Dictionary Block compression test : ", testNb++); + result = ZSTD_compressBegin(cctx, 5); + if (ZSTD_isError(result)) goto _output_error; + result = ZSTD_compress_insertDictionary(cctx, CNBuffer, dictSize); + if (ZSTD_isError(result)) goto _output_error; + cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize); + if (ZSTD_isError(cSize)) goto _output_error; + DISPLAYLEVEL(4, "OK \n"); + + DISPLAYLEVEL(4, "test%3i : Dictionary Block decompression test : ", testNb++); + result = ZSTD_resetDCtx(dctx); + if (ZSTD_isError(result)) goto _output_error; + ZSTD_decompress_insertDictionary(dctx, CNBuffer, dictSize); + result = ZSTD_decompressBlock(dctx, decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize); + if (ZSTD_isError(result)) goto _output_error; + if (result != blockSize) goto _output_error; + DISPLAYLEVEL(4, "OK \n"); + ZSTD_freeCCtx(cctx); ZSTD_freeDCtx(dctx); }