more complete support for literals repeat mode

This commit is contained in:
Yann Collet
2016-07-22 15:04:25 +02:00
parent 9f2d82d4a4
commit 772d912c2f
+17 -27
View File
@@ -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 */
} }
}
} }