commit
7b5948cca7
@ -168,9 +168,11 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
{
|
{
|
||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
/* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
|
/* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
if (iSize >= 128) { /* special header */
|
||||||
@ -198,6 +200,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
} }
|
} }
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
{ U32 const tableLog = BIT_highbit32(weightTotal) + 1;
|
{ U32 const tableLog = BIT_highbit32(weightTotal) + 1;
|
||||||
|
@ -2448,6 +2448,20 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Dictionaries that assign zero probability to symbols that show up causes problems
|
||||||
|
when FSE encoding. Refuse dictionaries that assign zero probability to symbols
|
||||||
|
that we may encounter during compression.
|
||||||
|
NOTE: This behavior is not standard and could be improved in the future. */
|
||||||
|
static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
|
||||||
|
U32 s;
|
||||||
|
if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
|
||||||
|
for (s = 0; s <= maxSymbolValue; ++s) {
|
||||||
|
if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Dictionary format :
|
/* Dictionary format :
|
||||||
Magic == ZSTD_DICT_MAGIC (4 bytes)
|
Magic == ZSTD_DICT_MAGIC (4 bytes)
|
||||||
HUF_writeCTable(256)
|
HUF_writeCTable(256)
|
||||||
@ -2464,32 +2478,41 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
{
|
{
|
||||||
const BYTE* dictPtr = (const BYTE*)dict;
|
const BYTE* dictPtr = (const BYTE*)dict;
|
||||||
const BYTE* const dictEnd = dictPtr + dictSize;
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
||||||
|
short offcodeNCount[MaxOff+1];
|
||||||
|
unsigned offcodeMaxValue = MaxOff;
|
||||||
|
|
||||||
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
||||||
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
dictPtr += hufHeaderSize;
|
dictPtr += hufHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ unsigned offcodeLog;
|
||||||
unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
|
|
||||||
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||||
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
||||||
CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||||
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||||
|
/* Every match length code must have non-zero probability */
|
||||||
|
CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
||||||
CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||||
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||||
|
/* Every literal length code must have non-zero probability */
|
||||||
|
CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
||||||
CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
@ -2500,6 +2523,16 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
dictPtr += 12;
|
dictPtr += 12;
|
||||||
|
|
||||||
|
{ U32 offcodeMax = MaxOff;
|
||||||
|
if ((size_t)(dictEnd - dictPtr) <= ((U32)-1) - 128 KB) {
|
||||||
|
U32 const maxOffset = (U32)(dictEnd - dictPtr) + 128 KB; /* The maximum offset that must be supported */
|
||||||
|
/* Calculate minimum offset code required to represent maxOffset */
|
||||||
|
offcodeMax = ZSTD_highbit32(maxOffset);
|
||||||
|
}
|
||||||
|
/* Every possible supported offset <= dictContentSize + 128 KB must be representable */
|
||||||
|
CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
|
||||||
|
}
|
||||||
|
|
||||||
cctx->flagStaticTables = 1;
|
cctx->flagStaticTables = 1;
|
||||||
return dictPtr - (const BYTE*)dict;
|
return dictPtr - (const BYTE*)dict;
|
||||||
}
|
}
|
||||||
|
@ -712,10 +712,13 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||||||
{ int nbSeq = *ip++;
|
{ int nbSeq = *ip++;
|
||||||
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
||||||
if (nbSeq > 0x7F) {
|
if (nbSeq > 0x7F) {
|
||||||
if (nbSeq == 0xFF)
|
if (nbSeq == 0xFF) {
|
||||||
|
if (ip+2 > iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
||||||
else
|
} else {
|
||||||
|
if (ip >= iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*nbSeqPtr = nbSeq;
|
*nbSeqPtr = nbSeq;
|
||||||
}
|
}
|
||||||
@ -1318,25 +1321,28 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t c
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog;
|
||||||
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||||
CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||||
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||||
CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||||
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||||
CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
@ -958,13 +958,16 @@ static size_t HUF_readDTable (U16* DTable, const void* src, size_t srcSize)
|
|||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
U32 maxBits;
|
U32 maxBits;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
U32 n;
|
U32 n;
|
||||||
U32 nextRankStart;
|
U32 nextRankStart;
|
||||||
void* ptr = DTable+1;
|
void* ptr = DTable+1;
|
||||||
HUF_DElt* const dt = (HUF_DElt*)ptr;
|
HUF_DElt* const dt = (HUF_DElt*)ptr;
|
||||||
|
|
||||||
|
if (!srcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
|
||||||
|
iSize = ip[0];
|
||||||
|
|
||||||
FSE_STATIC_ASSERT(sizeof(HUF_DElt) == sizeof(U16)); /* if compilation fails here, assertion is false */
|
FSE_STATIC_ASSERT(sizeof(HUF_DElt) == sizeof(U16)); /* if compilation fails here, assertion is false */
|
||||||
//memset(huffWeight, 0, sizeof(huffWeight)); /* should not be necessary, but some analyzer complain ... */
|
//memset(huffWeight, 0, sizeof(huffWeight)); /* should not be necessary, but some analyzer complain ... */
|
||||||
if (iSize >= 128) /* special header */
|
if (iSize >= 128) /* special header */
|
||||||
@ -1005,6 +1008,7 @@ static size_t HUF_readDTable (U16* DTable, const void* src, size_t srcSize)
|
|||||||
rankVal[huffWeight[n]]++;
|
rankVal[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
}
|
}
|
||||||
|
if (weightTotal == 0) return (size_t)-FSE_ERROR_corruptionDetected;
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
maxBits = FSE_highbit32(weightTotal) + 1;
|
maxBits = FSE_highbit32(weightTotal) + 1;
|
||||||
@ -1533,6 +1537,7 @@ size_t ZSTDv01_decodeLiteralsBlock(void* ctx,
|
|||||||
{
|
{
|
||||||
size_t rleSize = litbp.origSize;
|
size_t rleSize = litbp.origSize;
|
||||||
if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall);
|
if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
memset(oend - rleSize, *ip, rleSize);
|
memset(oend - rleSize, *ip, rleSize);
|
||||||
*litStart = oend - rleSize;
|
*litStart = oend - rleSize;
|
||||||
*litSize = rleSize;
|
*litSize = rleSize;
|
||||||
|
@ -1607,10 +1607,12 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
U32 tableLog;
|
U32 tableLog;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
U32 n;
|
U32 n;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) /* special header */
|
if (iSize >= 128) /* special header */
|
||||||
@ -1652,6 +1654,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
}
|
}
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
tableLog = BIT_highbit32(weightTotal) + 1;
|
tableLog = BIT_highbit32(weightTotal) + 1;
|
||||||
|
@ -1604,10 +1604,12 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
U32 tableLog;
|
U32 tableLog;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
U32 n;
|
U32 n;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) /* special header */
|
if (iSize >= 128) /* special header */
|
||||||
@ -1649,6 +1651,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
}
|
}
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
tableLog = BIT_highbit32(weightTotal) + 1;
|
tableLog = BIT_highbit32(weightTotal) + 1;
|
||||||
|
@ -1896,10 +1896,12 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
U32 tableLog;
|
U32 tableLog;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
U32 n;
|
U32 n;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) /* special header */
|
if (iSize >= 128) /* special header */
|
||||||
@ -1941,6 +1943,7 @@ static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
}
|
}
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
tableLog = BIT_highbit32(weightTotal) + 1;
|
tableLog = BIT_highbit32(weightTotal) + 1;
|
||||||
|
@ -1873,10 +1873,12 @@ static size_t HUFv05_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
U32 tableLog;
|
U32 tableLog;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
U32 n;
|
U32 n;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
if (iSize >= 128) { /* special header */
|
||||||
@ -1910,6 +1912,7 @@ static size_t HUFv05_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
}
|
}
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
tableLog = BITv05_highbit32(weightTotal) + 1;
|
tableLog = BITv05_highbit32(weightTotal) + 1;
|
||||||
@ -2943,6 +2946,7 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx,
|
|||||||
{
|
{
|
||||||
size_t litSize, litCSize, singleStream=0;
|
size_t litSize, litCSize, singleStream=0;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
|
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
|
||||||
switch(lhSize)
|
switch(lhSize)
|
||||||
{
|
{
|
||||||
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
||||||
@ -2966,6 +2970,7 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
|
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
|
||||||
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUFv05_isError(singleStream ?
|
if (HUFv05_isError(singleStream ?
|
||||||
HUFv05_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
HUFv05_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
@ -2991,6 +2996,7 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx,
|
|||||||
lhSize=3;
|
lhSize=3;
|
||||||
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
||||||
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
||||||
|
if (litCSize + litSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
errorCode = HUFv05_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
errorCode = HUFv05_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
||||||
if (HUFv05_isError(errorCode)) return ERROR(corruption_detected);
|
if (HUFv05_isError(errorCode)) return ERROR(corruption_detected);
|
||||||
@ -3047,6 +3053,7 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx,
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
||||||
|
if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
|
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
|
||||||
@ -3080,17 +3087,22 @@ size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumps
|
|||||||
/* SeqHead */
|
/* SeqHead */
|
||||||
*nbSeq = *ip++;
|
*nbSeq = *ip++;
|
||||||
if (*nbSeq==0) return 1;
|
if (*nbSeq==0) return 1;
|
||||||
if (*nbSeq >= 128)
|
if (*nbSeq >= 128) {
|
||||||
|
if (ip >= iend) return ERROR(srcSize_wrong);
|
||||||
*nbSeq = ((nbSeq[0]-128)<<8) + *ip++;
|
*nbSeq = ((nbSeq[0]-128)<<8) + *ip++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip >= iend) return ERROR(srcSize_wrong);
|
||||||
LLtype = *ip >> 6;
|
LLtype = *ip >> 6;
|
||||||
Offtype = (*ip >> 4) & 3;
|
Offtype = (*ip >> 4) & 3;
|
||||||
MLtype = (*ip >> 2) & 3;
|
MLtype = (*ip >> 2) & 3;
|
||||||
if (*ip & 2) {
|
if (*ip & 2) {
|
||||||
|
if (ip+3 > iend) return ERROR(srcSize_wrong);
|
||||||
dumpsLength = ip[2];
|
dumpsLength = ip[2];
|
||||||
dumpsLength += ip[1] << 8;
|
dumpsLength += ip[1] << 8;
|
||||||
ip += 3;
|
ip += 3;
|
||||||
} else {
|
} else {
|
||||||
|
if (ip+2 > iend) return ERROR(srcSize_wrong);
|
||||||
dumpsLength = ip[1];
|
dumpsLength = ip[1];
|
||||||
dumpsLength += (ip[0] & 1) << 8;
|
dumpsLength += (ip[0] & 1) << 8;
|
||||||
ip += 2;
|
ip += 2;
|
||||||
@ -3669,11 +3681,11 @@ static size_t ZSTDv05_loadEntropy(ZSTDv05_DCtx* dctx, const void* dict, size_t d
|
|||||||
{
|
{
|
||||||
size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
|
size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
|
||||||
short offcodeNCount[MaxOff+1];
|
short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSEv05Log;
|
U32 offcodeMaxValue=MaxOff, offcodeLog;
|
||||||
short matchlengthNCount[MaxML+1];
|
short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSEv05Log;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||||
short litlengthNCount[MaxLL+1];
|
short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSEv05Log;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||||
|
|
||||||
hSize = HUFv05_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
hSize = HUFv05_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
||||||
if (HUFv05_isError(hSize)) return ERROR(dictionary_corrupted);
|
if (HUFv05_isError(hSize)) return ERROR(dictionary_corrupted);
|
||||||
@ -3682,6 +3694,7 @@ static size_t ZSTDv05_loadEntropy(ZSTDv05_DCtx* dctx, const void* dict, size_t d
|
|||||||
|
|
||||||
offcodeHeaderSize = FSEv05_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
offcodeHeaderSize = FSEv05_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
||||||
if (FSEv05_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (offcodeLog > OffFSEv05Log) return ERROR(dictionary_corrupted);
|
||||||
errorCode = FSEv05_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
errorCode = FSEv05_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + offcodeHeaderSize;
|
dict = (const char*)dict + offcodeHeaderSize;
|
||||||
@ -3689,12 +3702,14 @@ static size_t ZSTDv05_loadEntropy(ZSTDv05_DCtx* dctx, const void* dict, size_t d
|
|||||||
|
|
||||||
matchlengthHeaderSize = FSEv05_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
matchlengthHeaderSize = FSEv05_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
||||||
if (FSEv05_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (matchlengthLog > MLFSEv05Log) return ERROR(dictionary_corrupted);
|
||||||
errorCode = FSEv05_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
errorCode = FSEv05_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + matchlengthHeaderSize;
|
dict = (const char*)dict + matchlengthHeaderSize;
|
||||||
dictSize -= matchlengthHeaderSize;
|
dictSize -= matchlengthHeaderSize;
|
||||||
|
|
||||||
litlengthHeaderSize = FSEv05_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
litlengthHeaderSize = FSEv05_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
||||||
|
if (litlengthLog > LLFSEv05Log) return ERROR(dictionary_corrupted);
|
||||||
if (FSEv05_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
errorCode = FSEv05_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
errorCode = FSEv05_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted);
|
||||||
|
@ -1932,9 +1932,11 @@ MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankSta
|
|||||||
{
|
{
|
||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
if (iSize >= 128) { /* special header */
|
||||||
@ -1969,6 +1971,7 @@ MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankSta
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
} }
|
} }
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
{ U32 const tableLog = BITv06_highbit32(weightTotal) + 1;
|
{ U32 const tableLog = BITv06_highbit32(weightTotal) + 1;
|
||||||
@ -3183,6 +3186,7 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
|
|||||||
lhSize=3;
|
lhSize=3;
|
||||||
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
||||||
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
||||||
|
if (litCSize + litSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
{ size_t const errorCode = HUFv06_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
{ size_t const errorCode = HUFv06_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
||||||
if (HUFv06_isError(errorCode)) return ERROR(corruption_detected);
|
if (HUFv06_isError(errorCode)) return ERROR(corruption_detected);
|
||||||
@ -3302,10 +3306,13 @@ size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
|
|||||||
{ int nbSeq = *ip++;
|
{ int nbSeq = *ip++;
|
||||||
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
||||||
if (nbSeq > 0x7F) {
|
if (nbSeq > 0x7F) {
|
||||||
if (nbSeq == 0xFF)
|
if (nbSeq == 0xFF) {
|
||||||
|
if (ip+2 > iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
||||||
else
|
} else {
|
||||||
|
if (ip >= iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*nbSeqPtr = nbSeq;
|
*nbSeqPtr = nbSeq;
|
||||||
}
|
}
|
||||||
@ -3827,9 +3834,10 @@ static size_t ZSTDv06_loadEntropy(ZSTDv06_DCtx* dctx, const void* dict, size_t d
|
|||||||
dictSize -= hSize;
|
dictSize -= hSize;
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog;
|
||||||
offcodeHeaderSize = FSEv06_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
offcodeHeaderSize = FSEv06_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
||||||
if (FSEv06_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv06_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv06_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dict = (const char*)dict + offcodeHeaderSize;
|
dict = (const char*)dict + offcodeHeaderSize;
|
||||||
@ -3837,9 +3845,10 @@ static size_t ZSTDv06_loadEntropy(ZSTDv06_DCtx* dctx, const void* dict, size_t d
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||||
matchlengthHeaderSize = FSEv06_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
matchlengthHeaderSize = FSEv06_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
||||||
if (FSEv06_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv06_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv06_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dict = (const char*)dict + matchlengthHeaderSize;
|
dict = (const char*)dict + matchlengthHeaderSize;
|
||||||
@ -3847,9 +3856,10 @@ static size_t ZSTDv06_loadEntropy(ZSTDv06_DCtx* dctx, const void* dict, size_t d
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||||
litlengthHeaderSize = FSEv06_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
litlengthHeaderSize = FSEv06_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
||||||
if (FSEv06_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv06_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv06_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
}
|
}
|
||||||
|
@ -1382,9 +1382,11 @@ size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
{
|
{
|
||||||
U32 weightTotal;
|
U32 weightTotal;
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
size_t iSize = ip[0];
|
size_t iSize;
|
||||||
size_t oSize;
|
size_t oSize;
|
||||||
|
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
iSize = ip[0];
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
if (iSize >= 128) { /* special header */
|
||||||
@ -1419,6 +1421,7 @@ size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
rankStats[huffWeight[n]]++;
|
rankStats[huffWeight[n]]++;
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
} }
|
} }
|
||||||
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
{ U32 const tableLog = BITv07_highbit32(weightTotal) + 1;
|
{ U32 const tableLog = BITv07_highbit32(weightTotal) + 1;
|
||||||
@ -3529,10 +3532,13 @@ size_t ZSTDv07_decodeSeqHeaders(int* nbSeqPtr,
|
|||||||
{ int nbSeq = *ip++;
|
{ int nbSeq = *ip++;
|
||||||
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
||||||
if (nbSeq > 0x7F) {
|
if (nbSeq > 0x7F) {
|
||||||
if (nbSeq == 0xFF)
|
if (nbSeq == 0xFF) {
|
||||||
|
if (ip+2 > iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
||||||
else
|
} else {
|
||||||
|
if (ip >= iend) return ERROR(srcSize_wrong);
|
||||||
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*nbSeqPtr = nbSeq;
|
*nbSeqPtr = nbSeq;
|
||||||
}
|
}
|
||||||
@ -4102,27 +4108,30 @@ static size_t ZSTDv07_loadEntropy(ZSTDv07_DCtx* dctx, const void* const dict, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog;
|
||||||
size_t const offcodeHeaderSize = FSEv07_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
size_t const offcodeHeaderSize = FSEv07_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSEv07_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv07_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv07_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
{ size_t const errorCode = FSEv07_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||||
size_t const matchlengthHeaderSize = FSEv07_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const matchlengthHeaderSize = FSEv07_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSEv07_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv07_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv07_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
{ size_t const errorCode = FSEv07_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||||
size_t const litlengthHeaderSize = FSEv07_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
size_t const litlengthHeaderSize = FSEv07_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSEv07_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSEv07_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSEv07_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
{ size_t const errorCode = FSEv07_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user