diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 562a6b17bc9..96be6cf8db4 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -155,7 +155,14 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, } assert(optPtr->symbolCosts != NULL); - if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { + /* The dictionary's FSE tables are only complete when every repeat + * mode is valid. A table with missing symbols returns a fake cost + * of tableLog + 1 from FSE_getMaxNbBits(), which is not a valid input + * to the scaled frequency calculation below. */ + if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid && + optPtr->symbolCosts->fse.litlength_repeatMode == FSE_repeat_valid && + optPtr->symbolCosts->fse.matchlength_repeatMode == FSE_repeat_valid && + optPtr->symbolCosts->fse.offcode_repeatMode == FSE_repeat_valid) { /* huffman stats covering the full value set : table presumed generated by dictionary */ optPtr->priceType = zop_dynamic;