diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c index beeff7a508f..30a2c65dee0 100644 --- a/lib/dictBuilder/cover.c +++ b/lib/dictBuilder/cover.c @@ -640,25 +640,14 @@ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples; const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize; const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize; - const size_t readLength = MAX(d, sizeof(U64); ctx->displayLevel = displayLevel; /* Checks */ - if (totalSamplesSize < readLength) || + if (totalSamplesSize < MAX(d, sizeof(U64)) || totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) { DISPLAYLEVEL(1, "Total samples size is too large (%u MB), maximum size is %u MB\n", (unsigned)(totalSamplesSize>>20), (COVER_MAX_SAMPLES_SIZE >> 20)); return ERROR(srcSize_wrong); } - /* The training set must be large enough for the partial suffix array, whose - * size is `trainingSamplesSize - MAX(d, sizeof(U64)) + 1`. When splitPoint - * < 1.0 the training set is a subset of the corpus, so it can be smaller - * than the total even after the check above. Guard against the size_t - * subtraction underflowing into a huge allocation. */ - if (trainingSamplesSize < MAX(d, sizeof(U64))) { - DISPLAYLEVEL(1, "Training samples size is too small (%u), minimum size is %u\n", - (unsigned)trainingSamplesSize, (unsigned)MAX(d, sizeof(U64))); - return ERROR(srcSize_wrong); - } /* Check if there are at least 5 training samples */ if (nbTrainSamples < 5) { DISPLAYLEVEL(1, "Total number of training samples is %u and is invalid.", nbTrainSamples); @@ -681,7 +670,7 @@ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, ctx->nbTrainSamples = nbTrainSamples; ctx->nbTestSamples = nbTestSamples; /* Partial suffix array */ - ctx->suffixSize = trainingSamplesSize - readLength + 1; + ctx->suffixSize = trainingSamplesSize - MAX(d, sizeof(U64)) + 1; ctx->suffix = (U32 *)malloc(ctx->suffixSize * sizeof(U32)); /* Maps index to the dmerID */ ctx->dmerAt = (U32 *)malloc(ctx->suffixSize * sizeof(U32)); diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 4a2f0bac8f8..346ef5c82ef 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -4260,25 +4260,6 @@ static int basicUnitTests(U32 const seed, double compressibility) if (dictID==0) goto _output_error; DISPLAYLEVEL(3, "OK : %u \n", (unsigned)dictID); - DISPLAYLEVEL(3, "test%3i : ZDICT_optimizeTrainFromBuffer_cover with tiny training set : ", testNb++); - { /* With splitPoint < 1.0 the training set is a subset of the corpus. - * If that subset is smaller than MAX(d, sizeof(U64)) the partial - * suffix array size used to underflow size_t (issue #4682). The - * builder must reject it cleanly instead. The first few samples are - * tiny so the 0.75 training split stays below the threshold, while - * the total corpus is comfortably large. */ - size_t tinySizes[8] = { 1, 1, 1, 1, 1, 1, 100, 100 }; - ZDICT_cover_params_t tinyParams; - size_t tinyResult; - memset(&tinyParams, 0, sizeof(tinyParams)); - tinyParams.steps = 4; - tinyParams.splitPoint = 0.75; - tinyResult = ZDICT_optimizeTrainFromBuffer_cover( - dictBuffer, optDictSize, CNBuffer, tinySizes, 8, &tinyParams); - if (!ZDICT_isError(tinyResult)) goto _output_error; - } - DISPLAYLEVEL(3, "OK \n"); - ZSTD_freeCCtx(cctx); free(dictBuffer); free(samplesSizes);