Fix ZSTD_getOffsetInfo() when nbSeq == 0
In 32-bit mode, ZSTD_getOffsetInfo() can be called when nbSeq == 0, and in this case the offset table is uninitialized. The function should just return 0 for both values, because there are no sequences. Credit to OSS-Fuzz
This commit is contained in:
committed by
Nick Terrell
parent
31e41b3d5e
commit
71a0259247
@@ -2008,14 +2008,18 @@ typedef struct {
|
|||||||
* as well as the maximum number additional bits required.
|
* as well as the maximum number additional bits required.
|
||||||
*/
|
*/
|
||||||
static ZSTD_OffsetInfo
|
static ZSTD_OffsetInfo
|
||||||
ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable)
|
ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable, int nbSeq)
|
||||||
{
|
{
|
||||||
|
ZSTD_OffsetInfo info = {0, 0};
|
||||||
|
/* If nbSeq == 0, then the offTable is uninitialized, but we have
|
||||||
|
* no sequences, so both values should be 0.
|
||||||
|
*/
|
||||||
|
if (nbSeq != 0) {
|
||||||
const void* ptr = offTable;
|
const void* ptr = offTable;
|
||||||
U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
|
U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
|
||||||
const ZSTD_seqSymbol* table = offTable + 1;
|
const ZSTD_seqSymbol* table = offTable + 1;
|
||||||
U32 const max = 1 << tableLog;
|
U32 const max = 1 << tableLog;
|
||||||
U32 u;
|
U32 u;
|
||||||
ZSTD_OffsetInfo info = {0, 0};
|
|
||||||
DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
|
DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
|
||||||
|
|
||||||
assert(max <= (1 << OffFSELog)); /* max not too large */
|
assert(max <= (1 << OffFSELog)); /* max not too large */
|
||||||
@@ -2026,6 +2030,7 @@ ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable)
|
|||||||
|
|
||||||
assert(tableLog <= OffFSELog);
|
assert(tableLog <= OffFSELog);
|
||||||
info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */
|
info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -2126,7 +2131,7 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|||||||
* NOTE: could probably use a larger nbSeq limit
|
* NOTE: could probably use a larger nbSeq limit
|
||||||
*/
|
*/
|
||||||
if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) {
|
if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) {
|
||||||
ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr);
|
ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq);
|
||||||
if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) {
|
if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) {
|
||||||
/* If isLongOffset, but the maximum number of additional bits that we see in our table is small
|
/* If isLongOffset, but the maximum number of additional bits that we see in our table is small
|
||||||
* enough, then we know it is impossible to have too long an offset in this block, so we can
|
* enough, then we know it is impossible to have too long an offset in this block, so we can
|
||||||
|
|||||||
Reference in New Issue
Block a user