Fix 2 bugs in dictionary loading
* Silently skip dictionaries less than 8 bytes, unless using `ZSTD_dct_fullDict`. This changes the compressor, which silently skips dictionaries <= 8 bytes. * Allow repcodes that are equal to the dictionary content size, since it is in bounds.
This commit is contained in:
parent
75e7c0d107
commit
60205fec02
@ -2771,7 +2771,7 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
||||
/*! ZSTD_loadZstdDictionary() :
|
||||
* @return : dictID, or an error code
|
||||
* assumptions : magic number supposed already checked
|
||||
* dictSize supposed > 8
|
||||
* dictSize supposed >= 8
|
||||
*/
|
||||
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
ZSTD_matchState_t* ms,
|
||||
@ -2788,7 +2788,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
size_t dictID;
|
||||
|
||||
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
||||
assert(dictSize > 8);
|
||||
assert(dictSize >= 8);
|
||||
assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
|
||||
|
||||
dictPtr += 4; /* skip magic number */
|
||||
@ -2890,7 +2890,10 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
void* workspace)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
|
||||
if ((dict==NULL) || (dictSize<=8)) return 0;
|
||||
if ((dict==NULL) || (dictSize<8)) {
|
||||
RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_reset_compressedBlockState(bs);
|
||||
|
||||
@ -2942,7 +2945,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
||||
|
||||
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
|
||||
ZSTDcrp_makeClean, zbuff) );
|
||||
{ size_t const dictID = cdict ?
|
||||
{ size_t const dictID = cdict ?
|
||||
ZSTD_compress_insertDictionary(
|
||||
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
||||
&cctx->workspace, params, cdict->dictContent, cdict->dictContentSize,
|
||||
@ -3219,7 +3222,7 @@ static size_t ZSTD_initCDict_internal(
|
||||
ZSTDirp_reset,
|
||||
ZSTD_resetTarget_CDict));
|
||||
/* (Maybe) load the dictionary
|
||||
* Skips loading the dictionary if it is <= 8 bytes.
|
||||
* Skips loading the dictionary if it is < 8 bytes.
|
||||
*/
|
||||
{ ZSTD_CCtx_params params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
@ -1096,7 +1096,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
||||
size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
|
||||
for (i=0; i<3; i++) {
|
||||
U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
|
||||
RETURN_ERROR_IF(rep==0 || rep >= dictContentSize,
|
||||
RETURN_ERROR_IF(rep==0 || rep > dictContentSize,
|
||||
dictionary_corrupted);
|
||||
entropy->rep[i] = rep;
|
||||
} }
|
||||
@ -1265,7 +1265,7 @@ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
|
||||
{
|
||||
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
||||
ZSTD_clearDict(dctx);
|
||||
if (dict && dictSize >= 8) {
|
||||
if (dict && dictSize != 0) {
|
||||
dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
|
||||
RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation);
|
||||
dctx->ddict = dctx->ddictLocal;
|
||||
|
@ -74,7 +74,7 @@ FUZZ_TARGETS := \
|
||||
dictionary_decompress \
|
||||
zstd_frame_info \
|
||||
simple_compress \
|
||||
dict_loader
|
||||
dictionary_loader
|
||||
|
||||
all: $(FUZZ_TARGETS)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user