decompression validates frame content checksum
This commit is contained in:
parent
c4f739bef4
commit
8e3a36a6db
@ -102,6 +102,7 @@ ERR_STATIC const char* ERR_getErrorString(ERR_enum code)
|
|||||||
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
|
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
|
||||||
case PREFIX(srcSize_wrong): return "Src size incorrect";
|
case PREFIX(srcSize_wrong): return "Src size incorrect";
|
||||||
case PREFIX(corruption_detected): return "Corrupted block detected";
|
case PREFIX(corruption_detected): return "Corrupted block detected";
|
||||||
|
case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
|
||||||
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
|
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
|
||||||
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
|
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
|
||||||
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
|
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
|
||||||
|
@ -54,6 +54,7 @@ typedef enum {
|
|||||||
ZSTD_error_dstSize_tooSmall,
|
ZSTD_error_dstSize_tooSmall,
|
||||||
ZSTD_error_srcSize_wrong,
|
ZSTD_error_srcSize_wrong,
|
||||||
ZSTD_error_corruption_detected,
|
ZSTD_error_corruption_detected,
|
||||||
|
ZSTD_error_checksum_wrong,
|
||||||
ZSTD_error_tableLog_tooLarge,
|
ZSTD_error_tableLog_tooLarge,
|
||||||
ZSTD_error_maxSymbolValue_tooLarge,
|
ZSTD_error_maxSymbolValue_tooLarge,
|
||||||
ZSTD_error_maxSymbolValue_tooSmall,
|
ZSTD_error_maxSymbolValue_tooSmall,
|
||||||
|
@ -148,12 +148,6 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_DCtx* ZSTD_createDCtx(void)
|
|
||||||
{
|
|
||||||
ZSTD_customMem customMem = { NULL, NULL };
|
|
||||||
return ZSTD_createDCtx_advanced(customMem);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
ZSTD_DCtx* dctx;
|
ZSTD_DCtx* dctx;
|
||||||
@ -180,6 +174,12 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
|||||||
return dctx;
|
return dctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZSTD_DCtx* ZSTD_createDCtx(void)
|
||||||
|
{
|
||||||
|
ZSTD_customMem const customMem = { NULL, NULL };
|
||||||
|
return ZSTD_createDCtx_advanced(customMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
@ -340,9 +340,9 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
BYTE const checkByte = ip[5];
|
BYTE const checkByte = ip[5];
|
||||||
size_t pos = ZSTD_frameHeaderSize_min;
|
size_t pos = ZSTD_frameHeaderSize_min;
|
||||||
U32 const dictIDSizeCode = checkByte&3;
|
U32 const dictIDSizeCode = checkByte&3;
|
||||||
fparamsPtr->windowLog = (allocByte & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
|
||||||
if ((allocByte & 0x30) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
|
if ((allocByte & 0x30) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
|
||||||
if ((checkByte & 0xEC) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
|
if ((checkByte & 0xEC) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */
|
||||||
|
fparamsPtr->windowLog = (allocByte & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
||||||
fparamsPtr->checksumFlag = checkByte & 0x10;
|
fparamsPtr->checksumFlag = checkByte & 0x10;
|
||||||
switch(dictIDSizeCode) /* fcsId */
|
switch(dictIDSizeCode) /* fcsId */
|
||||||
{
|
{
|
||||||
@ -961,6 +961,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
if (cBlockSize == 0) break; /* bt_end */
|
if (cBlockSize == 0) break; /* bt_end */
|
||||||
|
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
|
||||||
op += decodedSize;
|
op += decodedSize;
|
||||||
ip += cBlockSize;
|
ip += cBlockSize;
|
||||||
remainingSize -= cBlockSize;
|
remainingSize -= cBlockSize;
|
||||||
@ -1065,6 +1066,13 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
||||||
if (bp.blockType == bt_end) {
|
if (bp.blockType == bt_end) {
|
||||||
|
if (dctx->fParams.checksumFlag) {
|
||||||
|
U64 const h64 = XXH64_digest(&dctx->xxhState);
|
||||||
|
U32 const h32 = (U32)(h64>>11) & ((1<<22)-1);
|
||||||
|
const BYTE* const ip = (const BYTE*)src;
|
||||||
|
U32 const check32 = ip[2] + (ip[1] << 8) + ((ip[0] & 0x3F) << 16);
|
||||||
|
if (check32 != h32) return ERROR(checksum_wrong);
|
||||||
|
}
|
||||||
dctx->expected = 0;
|
dctx->expected = 0;
|
||||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
} else {
|
} else {
|
||||||
@ -1096,6 +1104,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
dctx->stage = ZSTDds_decodeBlockHeader;
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
dctx->expected = ZSTD_blockHeaderSize;
|
dctx->expected = ZSTD_blockHeaderSize;
|
||||||
dctx->previousDstEnd = (char*)dst + rSize;
|
dctx->previousDstEnd = (char*)dst + rSize;
|
||||||
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
|
||||||
return rSize;
|
return rSize;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1112,18 +1121,19 @@ static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSi
|
|||||||
dctx->previousDstEnd = (const char*)dict + dictSize;
|
dctx->previousDstEnd = (const char*)dict + dictSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t const dictSizeStart)
|
||||||
{
|
{
|
||||||
size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize;
|
size_t dictSize = dictSizeStart;
|
||||||
|
|
||||||
hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
{ size_t const hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
||||||
if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + hSize;
|
dict = (const char*)dict + hSize;
|
||||||
dictSize -= hSize;
|
dictSize -= hSize;
|
||||||
|
}
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
||||||
offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
@ -1133,7 +1143,7 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSiz
|
|||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
||||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
@ -1143,14 +1153,15 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSiz
|
|||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
||||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dictSize -= litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
dctx->flagRepeatTable = 1;
|
dctx->flagRepeatTable = 1;
|
||||||
return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
|
return dictSizeStart - dictSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
Loading…
Reference in New Issue
Block a user