more complete support for literals repeat mode
This commit is contained in:
@@ -460,14 +460,18 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src,
|
|||||||
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||||
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE*) src;
|
|
||||||
|
|
||||||
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
||||||
|
|
||||||
switch((litBlockType_t)(istart[0] & 3))
|
{ const BYTE* const istart = (const BYTE*) src;
|
||||||
|
litBlockType_t const litBlockType = (litBlockType_t)(istart[0] & 3);
|
||||||
|
|
||||||
|
switch(litBlockType)
|
||||||
{
|
{
|
||||||
|
case lbt_repeat:
|
||||||
|
if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
|
||||||
|
/* fall-through */
|
||||||
case lbt_huffman:
|
case lbt_huffman:
|
||||||
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
|
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
|
||||||
{ size_t lhSize, litSize, litCSize;
|
{ size_t lhSize, litSize, litCSize;
|
||||||
U32 singleStream=0;
|
U32 singleStream=0;
|
||||||
U32 const lhlCode = (istart[0] >> 2) & 3;
|
U32 const lhlCode = (istart[0] >> 2) & 3;
|
||||||
@@ -500,9 +504,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUF_isError(singleStream ?
|
if (HUF_isError((litBlockType==lbt_repeat) ?
|
||||||
|
( singleStream ?
|
||||||
|
HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) :
|
||||||
|
HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) ) :
|
||||||
|
( singleStream ?
|
||||||
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
|
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
|
||||||
return ERROR(corruption_detected);
|
return ERROR(corruption_detected);
|
||||||
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
dctx->litPtr = dctx->litBuffer;
|
||||||
@@ -511,28 +519,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
dctx->litEntropy = 1;
|
dctx->litEntropy = 1;
|
||||||
return litCSize + lhSize;
|
return litCSize + lhSize;
|
||||||
}
|
}
|
||||||
case lbt_repeat:
|
|
||||||
{ size_t litSize, litCSize, lhSize;
|
|
||||||
U32 const lhc = MEM_readLE24(istart) >> 4;
|
|
||||||
if ((((istart[0]) >> 2) & 3) != 1) /* only case supported for now : small litSize, single stream */
|
|
||||||
return ERROR(corruption_detected);
|
|
||||||
if (dctx->litEntropy==0)
|
|
||||||
return ERROR(dictionary_corrupted);
|
|
||||||
|
|
||||||
/* 2 - 2 - 10 - 10 */
|
|
||||||
lhSize = 3;
|
|
||||||
litSize = lhc & 0x3FF;
|
|
||||||
litCSize = lhc >> 10;
|
|
||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
{ size_t const errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable);
|
|
||||||
if (HUF_isError(errorCode)) return ERROR(corruption_detected);
|
|
||||||
}
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
|
||||||
dctx->litSize = litSize;
|
|
||||||
return litCSize + lhSize;
|
|
||||||
}
|
|
||||||
case lbt_raw:
|
case lbt_raw:
|
||||||
{ size_t litSize, lhSize;
|
{ size_t litSize, lhSize;
|
||||||
U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
||||||
@@ -566,6 +553,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
return lhSize+litSize;
|
return lhSize+litSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
case lbt_rle:
|
case lbt_rle:
|
||||||
{ U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
{ U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
||||||
size_t litSize, lhSize;
|
size_t litSize, lhSize;
|
||||||
@@ -595,6 +583,8 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
default:
|
default:
|
||||||
return ERROR(corruption_detected); /* impossible */
|
return ERROR(corruption_detected); /* impossible */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user