mirror of
https://github.com/facebook/zstd.git
synced 2024-11-24 17:36:44 +08:00
[libzstd] Fix bug in Huffman decompresser
The zstd format specification doesn't enforce that Huffman compressed literals (including the table) have to be smaller than the uncompressed literals. The compressor will never Huffman compress literals if the compressed size is larger than the uncompressed size. The decompresser doesn't accept Huffman compressed literals with 4 streams whose compressed size is at least as large as the uncompressed size. * Make the decompresser accept Huffman compressed literals whose size increases. * Add a test case that exposes the bug. The compressed file has to be statically generated, since the compressor won't normally produce files that expose the bug.
This commit is contained in:
parent
e1222544be
commit
abe12b3399
@ -917,11 +917,11 @@ static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, qu
|
||||
* Tells which decoder is likely to decode faster,
|
||||
* based on a set of pre-determined metrics.
|
||||
* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
|
||||
* Assumption : 0 < cSrcSize < dstSize <= 128 KB */
|
||||
* Assumption : 0 < cSrcSize, dstSize <= 128 KB */
|
||||
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
|
||||
{
|
||||
/* decoder timing evaluation */
|
||||
U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
|
||||
U32 const Q = cSrcSize >= dstSize ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */
|
||||
U32 const D256 = (U32)(dstSize >> 8);
|
||||
U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
|
||||
U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
|
||||
@ -977,7 +977,7 @@ size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,
|
||||
{
|
||||
/* validation checks */
|
||||
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||
if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected); /* invalid */
|
||||
if (cSrcSize == 0) return ERROR(corruption_detected);
|
||||
|
||||
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||
return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize):
|
||||
|
BIN
tests/files/huffman-compressed-larger
Normal file
BIN
tests/files/huffman-compressed-larger
Normal file
Binary file not shown.
@ -386,6 +386,13 @@ $ZSTD -t tmpSplit.* && die "bad file not detected !"
|
||||
./datagen | $ZSTD -c | $ZSTD -t
|
||||
|
||||
|
||||
|
||||
$ECHO "\n**** golden files tests **** "
|
||||
|
||||
$ZSTD -t -r files
|
||||
$ZSTD -c -r files | $ZSTD -t
|
||||
|
||||
|
||||
$ECHO "\n**** benchmark mode tests **** "
|
||||
|
||||
$ECHO "bench one file"
|
||||
|
Loading…
Reference in New Issue
Block a user