Skip to content

Commit 81cf153

Browse files
Codyterrelln
authored andcommitted
fix: adjust LDM params in estimate functions to prevent SIGFPE (issue #4590)
1 parent 117b0ed commit 81cf153

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

lib/compress/zstd_compress.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,15 +1771,19 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
17711771
{
17721772
ZSTD_compressionParameters const cParams =
17731773
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
1774+
ldmParams_t ldmParams = params->ldmParams;
17741775
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
17751776
&cParams);
17761777

17771778
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
1779+
if (ldmParams.enableLdm == ZSTD_ps_enable) {
1780+
ZSTD_ldm_adjustParameters(&ldmParams, &cParams);
1781+
}
17781782
/* estimateCCtxSize is for one-shot compression. So no buffers should
17791783
* be needed. However, we still allocate two 0-sized buffers, which can
17801784
* take space under ASAN. */
17811785
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1782-
&cParams, &params->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
1786+
&cParams, &ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
17831787
}
17841788

17851789
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
@@ -1829,6 +1833,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
18291833
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
18301834
{ ZSTD_compressionParameters const cParams =
18311835
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
1836+
ldmParams_t ldmParams = params->ldmParams;
18321837
size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(params->maxBlockSize), (size_t)1 << cParams.windowLog);
18331838
size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
18341839
? ((size_t)1 << cParams.windowLog) + blockSize
@@ -1838,8 +1843,11 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
18381843
: 0;
18391844
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
18401845

1846+
if (ldmParams.enableLdm == ZSTD_ps_enable) {
1847+
ZSTD_ldm_adjustParameters(&ldmParams, &cParams);
1848+
}
18411849
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1842-
&cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
1850+
&cParams, &ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
18431851
ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
18441852
}
18451853
}

tests/fuzzer.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,25 @@ static int basicUnitTests(U32 const seed, double compressibility)
25152515
}
25162516
}
25172517
DISPLAYLEVEL(3, "OK \n");
2518+
2519+
DISPLAYLEVEL(3, "test%3i : estimation functions with LDM enabled (issue #4590) : ", testNb++);
2520+
{
2521+
/* ZSTD_estimateCCtxSize_usingCCtxParams must adjust zeroed-out
2522+
* LDM parameters when LDM is enabled, to avoid division by zero
2523+
* in ZSTD_ldm_getMaxNbSeq. */
2524+
ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
2525+
size_t cctxSize;
2526+
CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_compressionLevel, 22));
2527+
CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable));
2528+
cctxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
2529+
if (ZSTD_isError(cctxSize)) goto _output_error;
2530+
if (cctxSize == 0) goto _output_error;
2531+
cctxSize = ZSTD_estimateCStreamSize_usingCCtxParams(params);
2532+
if (ZSTD_isError(cctxSize)) goto _output_error;
2533+
if (cctxSize == 0) goto _output_error;
2534+
ZSTD_freeCCtxParams(params);
2535+
}
2536+
DISPLAYLEVEL(3, "OK \n");
25182537
}
25192538
free(staticCCtxBuffer);
25202539
free(staticDCtxBuffer);

0 commit comments

Comments
 (0)