| 3165 | } |
| 3166 | |
| 3167 | size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, |
| 3168 | const void* const dict, size_t dictSize) |
| 3169 | { |
| 3170 | short offcodeNCount[MaxOff+1]; |
| 3171 | unsigned offcodeMaxValue = MaxOff; |
| 3172 | const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */ |
| 3173 | const BYTE* const dictEnd = dictPtr + dictSize; |
| 3174 | dictPtr += 8; |
| 3175 | bs->entropy.huf.repeatMode = HUF_repeat_check; |
| 3176 | |
| 3177 | { unsigned maxSymbolValue = 255; |
| 3178 | unsigned hasZeroWeights = 1; |
| 3179 | size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, |
| 3180 | dictEnd-dictPtr, &hasZeroWeights); |
| 3181 | |
| 3182 | /* We only set the loaded table as valid if it contains all non-zero |
| 3183 | * weights. Otherwise, we set it to check */ |
| 3184 | if (!hasZeroWeights) |
| 3185 | bs->entropy.huf.repeatMode = HUF_repeat_valid; |
| 3186 | |
| 3187 | RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, ""); |
| 3188 | RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted, ""); |
| 3189 | dictPtr += hufHeaderSize; |
| 3190 | } |
| 3191 | |
| 3192 | { unsigned offcodeLog; |
| 3193 | size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); |
| 3194 | RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); |
| 3195 | RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); |
| 3196 | /* fill all offset symbols to avoid garbage at end of table */ |
| 3197 | RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( |
| 3198 | bs->entropy.fse.offcodeCTable, |
| 3199 | offcodeNCount, MaxOff, offcodeLog, |
| 3200 | workspace, HUF_WORKSPACE_SIZE)), |
| 3201 | dictionary_corrupted, ""); |
| 3202 | /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ |
| 3203 | dictPtr += offcodeHeaderSize; |
| 3204 | } |
| 3205 | |
| 3206 | { short matchlengthNCount[MaxML+1]; |
| 3207 | unsigned matchlengthMaxValue = MaxML, matchlengthLog; |
| 3208 | size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); |
| 3209 | RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); |
| 3210 | RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); |
| 3211 | RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( |
| 3212 | bs->entropy.fse.matchlengthCTable, |
| 3213 | matchlengthNCount, matchlengthMaxValue, matchlengthLog, |
| 3214 | workspace, HUF_WORKSPACE_SIZE)), |
| 3215 | dictionary_corrupted, ""); |
| 3216 | bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML); |
| 3217 | dictPtr += matchlengthHeaderSize; |
| 3218 | } |
| 3219 | |
| 3220 | { short litlengthNCount[MaxLL+1]; |
| 3221 | unsigned litlengthMaxValue = MaxLL, litlengthLog; |
| 3222 | size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); |
| 3223 | RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); |
| 3224 | RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); |
no test coverage detected