summaryrefslogtreecommitdiff
path: root/lib/legacy
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-08-08 15:30:49 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-08-08 15:30:49 +0000
commitfa94c7381af469a06d8f9077162c2cc5dee581cb (patch)
tree1f6152d1ad6531de48efbb231bb91e55ba0ac2e4 /lib/legacy
parent3f774a5e86430d45c78443d234a90ee54582564f (diff)
Diffstat (limited to 'lib/legacy')
-rw-r--r--lib/legacy/zstd_legacy.h4
-rw-r--r--lib/legacy/zstd_v01.c196
-rw-r--r--lib/legacy/zstd_v02.c17
-rw-r--r--lib/legacy/zstd_v03.c17
-rw-r--r--lib/legacy/zstd_v04.c19
-rw-r--r--lib/legacy/zstd_v05.c172
-rw-r--r--lib/legacy/zstd_v06.c6
-rw-r--r--lib/legacy/zstd_v07.c6
8 files changed, 224 insertions, 213 deletions
diff --git a/lib/legacy/zstd_legacy.h b/lib/legacy/zstd_legacy.h
index e5b383ee4c0ce..0dbd3c7a40f5d 100644
--- a/lib/legacy/zstd_legacy.h
+++ b/lib/legacy/zstd_legacy.h
@@ -238,6 +238,10 @@ MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size
frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
break;
}
+ if (!ZSTD_isError(frameSizeInfo.compressedSize) && frameSizeInfo.compressedSize > srcSize) {
+ frameSizeInfo.compressedSize = ERROR(srcSize_wrong);
+ frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
+ }
return frameSizeInfo;
}
diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c
index cad2b99b4a732..ae8cba2a3fa20 100644
--- a/lib/legacy/zstd_v01.c
+++ b/lib/legacy/zstd_v01.c
@@ -1073,99 +1073,102 @@ static size_t HUF_decompress_usingDTable( /* -3% slower when non static */
const void* cSrc, size_t cSrcSize,
const U16* DTable)
{
- BYTE* const ostart = (BYTE*) dst;
- BYTE* op = ostart;
- BYTE* const omax = op + maxDstSize;
- BYTE* const olimit = omax-15;
-
- const void* ptr = DTable;
- const HUF_DElt* const dt = (const HUF_DElt*)(ptr)+1;
- const U32 dtLog = DTable[0];
- size_t errorCode;
- U32 reloadStatus;
-
- /* Init */
-
- const U16* jumpTable = (const U16*)cSrc;
- const size_t length1 = FSE_readLE16(jumpTable);
- const size_t length2 = FSE_readLE16(jumpTable+1);
- const size_t length3 = FSE_readLE16(jumpTable+2);
- const size_t length4 = cSrcSize - 6 - length1 - length2 - length3; // check coherency !!
- const char* const start1 = (const char*)(cSrc) + 6;
- const char* const start2 = start1 + length1;
- const char* const start3 = start2 + length2;
- const char* const start4 = start3 + length3;
- FSE_DStream_t bitD1, bitD2, bitD3, bitD4;
-
- if (length1+length2+length3+6 >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
-
- errorCode = FSE_initDStream(&bitD1, start1, length1);
- if (FSE_isError(errorCode)) return errorCode;
- errorCode = FSE_initDStream(&bitD2, start2, length2);
- if (FSE_isError(errorCode)) return errorCode;
- errorCode = FSE_initDStream(&bitD3, start3, length3);
- if (FSE_isError(errorCode)) return errorCode;
- errorCode = FSE_initDStream(&bitD4, start4, length4);
- if (FSE_isError(errorCode)) return errorCode;
-
- reloadStatus=FSE_reloadDStream(&bitD2);
-
- /* 16 symbols per loop */
- for ( ; (reloadStatus<FSE_DStream_completed) && (op<olimit); /* D2-3-4 are supposed to be synchronized and finish together */
- op+=16, reloadStatus = FSE_reloadDStream(&bitD2) | FSE_reloadDStream(&bitD3) | FSE_reloadDStream(&bitD4), FSE_reloadDStream(&bitD1))
+ if (cSrcSize < 6) return (size_t)-FSE_ERROR_srcSize_wrong;
{
-#define HUF_DECODE_SYMBOL_0(n, Dstream) \
- op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog);
-
-#define HUF_DECODE_SYMBOL_1(n, Dstream) \
- op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
- if (FSE_32bits() && (HUF_MAX_TABLELOG>12)) FSE_reloadDStream(&Dstream)
-
-#define HUF_DECODE_SYMBOL_2(n, Dstream) \
- op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
- if (FSE_32bits()) FSE_reloadDStream(&Dstream)
-
- HUF_DECODE_SYMBOL_1( 0, bitD1);
- HUF_DECODE_SYMBOL_1( 1, bitD2);
- HUF_DECODE_SYMBOL_1( 2, bitD3);
- HUF_DECODE_SYMBOL_1( 3, bitD4);
- HUF_DECODE_SYMBOL_2( 4, bitD1);
- HUF_DECODE_SYMBOL_2( 5, bitD2);
- HUF_DECODE_SYMBOL_2( 6, bitD3);
- HUF_DECODE_SYMBOL_2( 7, bitD4);
- HUF_DECODE_SYMBOL_1( 8, bitD1);
- HUF_DECODE_SYMBOL_1( 9, bitD2);
- HUF_DECODE_SYMBOL_1(10, bitD3);
- HUF_DECODE_SYMBOL_1(11, bitD4);
- HUF_DECODE_SYMBOL_0(12, bitD1);
- HUF_DECODE_SYMBOL_0(13, bitD2);
- HUF_DECODE_SYMBOL_0(14, bitD3);
- HUF_DECODE_SYMBOL_0(15, bitD4);
- }
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* op = ostart;
+ BYTE* const omax = op + maxDstSize;
+ BYTE* const olimit = omax-15;
+
+ const void* ptr = DTable;
+ const HUF_DElt* const dt = (const HUF_DElt*)(ptr)+1;
+ const U32 dtLog = DTable[0];
+ size_t errorCode;
+ U32 reloadStatus;
+
+ /* Init */
+
+ const U16* jumpTable = (const U16*)cSrc;
+ const size_t length1 = FSE_readLE16(jumpTable);
+ const size_t length2 = FSE_readLE16(jumpTable+1);
+ const size_t length3 = FSE_readLE16(jumpTable+2);
+ const size_t length4 = cSrcSize - 6 - length1 - length2 - length3; // check coherency !!
+ const char* const start1 = (const char*)(cSrc) + 6;
+ const char* const start2 = start1 + length1;
+ const char* const start3 = start2 + length2;
+ const char* const start4 = start3 + length3;
+ FSE_DStream_t bitD1, bitD2, bitD3, bitD4;
+
+ if (length1+length2+length3+6 >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
+
+ errorCode = FSE_initDStream(&bitD1, start1, length1);
+ if (FSE_isError(errorCode)) return errorCode;
+ errorCode = FSE_initDStream(&bitD2, start2, length2);
+ if (FSE_isError(errorCode)) return errorCode;
+ errorCode = FSE_initDStream(&bitD3, start3, length3);
+ if (FSE_isError(errorCode)) return errorCode;
+ errorCode = FSE_initDStream(&bitD4, start4, length4);
+ if (FSE_isError(errorCode)) return errorCode;
+
+ reloadStatus=FSE_reloadDStream(&bitD2);
+
+ /* 16 symbols per loop */
+ for ( ; (reloadStatus<FSE_DStream_completed) && (op<olimit); /* D2-3-4 are supposed to be synchronized and finish together */
+ op+=16, reloadStatus = FSE_reloadDStream(&bitD2) | FSE_reloadDStream(&bitD3) | FSE_reloadDStream(&bitD4), FSE_reloadDStream(&bitD1))
+ {
+ #define HUF_DECODE_SYMBOL_0(n, Dstream) \
+ op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog);
+
+ #define HUF_DECODE_SYMBOL_1(n, Dstream) \
+ op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
+ if (FSE_32bits() && (HUF_MAX_TABLELOG>12)) FSE_reloadDStream(&Dstream)
+
+ #define HUF_DECODE_SYMBOL_2(n, Dstream) \
+ op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
+ if (FSE_32bits()) FSE_reloadDStream(&Dstream)
+
+ HUF_DECODE_SYMBOL_1( 0, bitD1);
+ HUF_DECODE_SYMBOL_1( 1, bitD2);
+ HUF_DECODE_SYMBOL_1( 2, bitD3);
+ HUF_DECODE_SYMBOL_1( 3, bitD4);
+ HUF_DECODE_SYMBOL_2( 4, bitD1);
+ HUF_DECODE_SYMBOL_2( 5, bitD2);
+ HUF_DECODE_SYMBOL_2( 6, bitD3);
+ HUF_DECODE_SYMBOL_2( 7, bitD4);
+ HUF_DECODE_SYMBOL_1( 8, bitD1);
+ HUF_DECODE_SYMBOL_1( 9, bitD2);
+ HUF_DECODE_SYMBOL_1(10, bitD3);
+ HUF_DECODE_SYMBOL_1(11, bitD4);
+ HUF_DECODE_SYMBOL_0(12, bitD1);
+ HUF_DECODE_SYMBOL_0(13, bitD2);
+ HUF_DECODE_SYMBOL_0(14, bitD3);
+ HUF_DECODE_SYMBOL_0(15, bitD4);
+ }
- if (reloadStatus!=FSE_DStream_completed) /* not complete : some bitStream might be FSE_DStream_unfinished */
- return (size_t)-FSE_ERROR_corruptionDetected;
+ if (reloadStatus!=FSE_DStream_completed) /* not complete : some bitStream might be FSE_DStream_unfinished */
+ return (size_t)-FSE_ERROR_corruptionDetected;
- /* tail */
- {
- // bitTail = bitD1; // *much* slower : -20% !??!
- FSE_DStream_t bitTail;
- bitTail.ptr = bitD1.ptr;
- bitTail.bitsConsumed = bitD1.bitsConsumed;
- bitTail.bitContainer = bitD1.bitContainer; // required in case of FSE_DStream_endOfBuffer
- bitTail.start = start1;
- for ( ; (FSE_reloadDStream(&bitTail) < FSE_DStream_completed) && (op<omax) ; op++)
+ /* tail */
{
- HUF_DECODE_SYMBOL_0(0, bitTail);
- }
+ // bitTail = bitD1; // *much* slower : -20% !??!
+ FSE_DStream_t bitTail;
+ bitTail.ptr = bitD1.ptr;
+ bitTail.bitsConsumed = bitD1.bitsConsumed;
+ bitTail.bitContainer = bitD1.bitContainer; // required in case of FSE_DStream_endOfBuffer
+ bitTail.start = start1;
+ for ( ; (FSE_reloadDStream(&bitTail) < FSE_DStream_completed) && (op<omax) ; op++)
+ {
+ HUF_DECODE_SYMBOL_0(0, bitTail);
+ }
- if (FSE_endOfDStream(&bitTail))
- return op-ostart;
- }
+ if (FSE_endOfDStream(&bitTail))
+ return op-ostart;
+ }
- if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
+ if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
- return (size_t)-FSE_ERROR_corruptionDetected;
+ return (size_t)-FSE_ERROR_corruptionDetected;
+ }
}
@@ -1355,8 +1358,6 @@ static unsigned ZSTD_isLittleEndian(void)
static U16 ZSTD_read16(const void* p) { U16 r; memcpy(&r, p, sizeof(r)); return r; }
-static U32 ZSTD_read32(const void* p) { U32 r; memcpy(&r, p, sizeof(r)); return r; }
-
static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
@@ -1381,16 +1382,9 @@ static U16 ZSTD_readLE16(const void* memPtr)
}
}
-
-static U32 ZSTD_readLE32(const void* memPtr)
+static U32 ZSTD_readLE24(const void* memPtr)
{
- if (ZSTD_isLittleEndian())
- return ZSTD_read32(memPtr);
- else
- {
- const BYTE* p = (const BYTE*)memPtr;
- return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24));
- }
+ return ZSTD_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
}
static U32 ZSTD_readBE32(const void* memPtr)
@@ -1704,13 +1698,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
seqState->prevOffset = seq->offset;
if (litLength == MaxLL)
{
- U32 add = dumps<de ? *dumps++ : 0;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) litLength += add;
else
{
if (dumps<=(de-3))
{
- litLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ litLength = ZSTD_readLE24(dumps);
dumps += 3;
}
}
@@ -1732,13 +1726,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML)
{
- U32 add = dumps<de ? *dumps++ : 0;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add;
else
{
if (dumps<=(de-3))
{
- matchLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ matchLength = ZSTD_readLE24(dumps);
dumps += 3;
}
}
diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c
index 561bc412e9a8e..793df6024bbd0 100644
--- a/lib/legacy/zstd_v02.c
+++ b/lib/legacy/zstd_v02.c
@@ -217,6 +217,11 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
}
}
+MEM_STATIC U32 MEM_readLE24(const void* memPtr)
+{
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
+}
+
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{
if (MEM_isLittleEndian())
@@ -3043,11 +3048,11 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
seqState->prevOffset = seq->offset;
if (litLength == MaxLL)
{
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) litLength += add;
- else
+ else if (dumps + 3 <= de)
{
- litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ litLength = MEM_readLE24(dumps);
dumps += 3;
}
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
@@ -3073,11 +3078,11 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML)
{
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add;
- else
+ else if (dumps + 3 <= de)
{
- matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ matchLength = MEM_readLE24(dumps);
dumps += 3;
}
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c
index a1bf0fa9b5c8b..7a0e7c9b69fb0 100644
--- a/lib/legacy/zstd_v03.c
+++ b/lib/legacy/zstd_v03.c
@@ -219,6 +219,11 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
}
}
+MEM_STATIC U32 MEM_readLE24(const void* memPtr)
+{
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
+}
+
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{
if (MEM_isLittleEndian())
@@ -2684,11 +2689,11 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
seqState->prevOffset = seq->offset;
if (litLength == MaxLL)
{
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) litLength += add;
- else
+ else if (dumps + 3 <= de)
{
- litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ litLength = MEM_readLE24(dumps);
dumps += 3;
}
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
@@ -2714,11 +2719,11 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML)
{
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add;
- else
+ else if (dumps + 3 <= de)
{
- matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ matchLength = MEM_readLE24(dumps);
dumps += 3;
}
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c
index 4342330e2553d..645a6e313c05f 100644
--- a/lib/legacy/zstd_v04.c
+++ b/lib/legacy/zstd_v04.c
@@ -189,6 +189,11 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
}
}
+MEM_STATIC U32 MEM_readLE24(const void* memPtr)
+{
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
+}
+
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{
if (MEM_isLittleEndian())
@@ -2808,13 +2813,12 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
prevOffset = litLength ? seq->offset : seqState->prevOffset;
if (litLength == MaxLL) {
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) litLength += add;
- else {
- litLength = dumps[0] + (dumps[1]<<8) + (dumps[2]<<16);
+ else if (dumps + 3 <= de) {
+ litLength = MEM_readLE24(dumps);
dumps += 3;
}
- if (dumps > de) { litLength = MaxLL+255; } /* late correction, to avoid using uninitialized memory */
if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
}
@@ -2837,13 +2841,12 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
/* MatchLength */
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML) {
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add;
- else {
- matchLength = dumps[0] + (dumps[1]<<8) + (dumps[2]<<16);
+ else if (dumps + 3 <= de){
+ matchLength = MEM_readLE24(dumps);
dumps += 3;
}
- if (dumps > de) { matchLength = MaxML+255; } /* late correction, to avoid using uninitialized memory */
if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
}
matchLength += MINMATCH;
diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c
index caaf15f9bdb1f..a7ea6066fb083 100644
--- a/lib/legacy/zstd_v05.c
+++ b/lib/legacy/zstd_v05.c
@@ -218,6 +218,11 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
}
}
+MEM_STATIC U32 MEM_readLE24(const void* memPtr)
+{
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
+}
+
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{
if (MEM_isLittleEndian())
@@ -1998,91 +2003,92 @@ size_t HUFv05_decompress4X2_usingDTable(
const void* cSrc, size_t cSrcSize,
const U16* DTable)
{
- const BYTE* const istart = (const BYTE*) cSrc;
- BYTE* const ostart = (BYTE*) dst;
- BYTE* const oend = ostart + dstSize;
- const void* const dtPtr = DTable;
- const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr) +1;
- const U32 dtLog = DTable[0];
- size_t errorCode;
-
- /* Init */
- BITv05_DStream_t bitD1;
- BITv05_DStream_t bitD2;
- BITv05_DStream_t bitD3;
- BITv05_DStream_t bitD4;
- const size_t length1 = MEM_readLE16(istart);
- const size_t length2 = MEM_readLE16(istart+2);
- const size_t length3 = MEM_readLE16(istart+4);
- size_t length4;
- const BYTE* const istart1 = istart + 6; /* jumpTable */
- const BYTE* const istart2 = istart1 + length1;
- const BYTE* const istart3 = istart2 + length2;
- const BYTE* const istart4 = istart3 + length3;
- const size_t segmentSize = (dstSize+3) / 4;
- BYTE* const opStart2 = ostart + segmentSize;
- BYTE* const opStart3 = opStart2 + segmentSize;
- BYTE* const opStart4 = opStart3 + segmentSize;
- BYTE* op1 = ostart;
- BYTE* op2 = opStart2;
- BYTE* op3 = opStart3;
- BYTE* op4 = opStart4;
- U32 endSignal;
-
/* Check */
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
+ {
+ const BYTE* const istart = (const BYTE*) cSrc;
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* const oend = ostart + dstSize;
+ const void* const dtPtr = DTable;
+ const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr) +1;
+ const U32 dtLog = DTable[0];
+ size_t errorCode;
- length4 = cSrcSize - (length1 + length2 + length3 + 6);
- if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
- errorCode = BITv05_initDStream(&bitD1, istart1, length1);
- if (HUFv05_isError(errorCode)) return errorCode;
- errorCode = BITv05_initDStream(&bitD2, istart2, length2);
- if (HUFv05_isError(errorCode)) return errorCode;
- errorCode = BITv05_initDStream(&bitD3, istart3, length3);
- if (HUFv05_isError(errorCode)) return errorCode;
- errorCode = BITv05_initDStream(&bitD4, istart4, length4);
- if (HUFv05_isError(errorCode)) return errorCode;
+ /* Init */
+ BITv05_DStream_t bitD1;
+ BITv05_DStream_t bitD2;
+ BITv05_DStream_t bitD3;
+ BITv05_DStream_t bitD4;
+ const size_t length1 = MEM_readLE16(istart);
+ const size_t length2 = MEM_readLE16(istart+2);
+ const size_t length3 = MEM_readLE16(istart+4);
+ size_t length4;
+ const BYTE* const istart1 = istart + 6; /* jumpTable */
+ const BYTE* const istart2 = istart1 + length1;
+ const BYTE* const istart3 = istart2 + length2;
+ const BYTE* const istart4 = istart3 + length3;
+ const size_t segmentSize = (dstSize+3) / 4;
+ BYTE* const opStart2 = ostart + segmentSize;
+ BYTE* const opStart3 = opStart2 + segmentSize;
+ BYTE* const opStart4 = opStart3 + segmentSize;
+ BYTE* op1 = ostart;
+ BYTE* op2 = opStart2;
+ BYTE* op3 = opStart3;
+ BYTE* op4 = opStart4;
+ U32 endSignal;
- /* 16-32 symbols per loop (4-8 symbols per stream) */
- endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
- for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) {
- HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUFv05_DECODE_SYMBOLX2_1(op1, &bitD1);
- HUFv05_DECODE_SYMBOLX2_1(op2, &bitD2);
- HUFv05_DECODE_SYMBOLX2_1(op3, &bitD3);
- HUFv05_DECODE_SYMBOLX2_1(op4, &bitD4);
- HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUFv05_DECODE_SYMBOLX2_0(op1, &bitD1);
- HUFv05_DECODE_SYMBOLX2_0(op2, &bitD2);
- HUFv05_DECODE_SYMBOLX2_0(op3, &bitD3);
- HUFv05_DECODE_SYMBOLX2_0(op4, &bitD4);
+ length4 = cSrcSize - (length1 + length2 + length3 + 6);
+ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
+ errorCode = BITv05_initDStream(&bitD1, istart1, length1);
+ if (HUFv05_isError(errorCode)) return errorCode;
+ errorCode = BITv05_initDStream(&bitD2, istart2, length2);
+ if (HUFv05_isError(errorCode)) return errorCode;
+ errorCode = BITv05_initDStream(&bitD3, istart3, length3);
+ if (HUFv05_isError(errorCode)) return errorCode;
+ errorCode = BITv05_initDStream(&bitD4, istart4, length4);
+ if (HUFv05_isError(errorCode)) return errorCode;
+
+ /* 16-32 symbols per loop (4-8 symbols per stream) */
endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
- }
+ for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) {
+ HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUFv05_DECODE_SYMBOLX2_1(op1, &bitD1);
+ HUFv05_DECODE_SYMBOLX2_1(op2, &bitD2);
+ HUFv05_DECODE_SYMBOLX2_1(op3, &bitD3);
+ HUFv05_DECODE_SYMBOLX2_1(op4, &bitD4);
+ HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUFv05_DECODE_SYMBOLX2_0(op1, &bitD1);
+ HUFv05_DECODE_SYMBOLX2_0(op2, &bitD2);
+ HUFv05_DECODE_SYMBOLX2_0(op3, &bitD3);
+ HUFv05_DECODE_SYMBOLX2_0(op4, &bitD4);
+ endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
+ }
- /* check corruption */
- if (op1 > opStart2) return ERROR(corruption_detected);
- if (op2 > opStart3) return ERROR(corruption_detected);
- if (op3 > opStart4) return ERROR(corruption_detected);
- /* note : op4 supposed already verified within main loop */
+ /* check corruption */
+ if (op1 > opStart2) return ERROR(corruption_detected);
+ if (op2 > opStart3) return ERROR(corruption_detected);
+ if (op3 > opStart4) return ERROR(corruption_detected);
+ /* note : op4 supposed already verified within main loop */
- /* finish bitStreams one by one */
- HUFv05_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
- HUFv05_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
- HUFv05_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
- HUFv05_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
+ /* finish bitStreams one by one */
+ HUFv05_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
+ HUFv05_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
+ HUFv05_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
+ HUFv05_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
- /* check */
- endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4);
- if (!endSignal) return ERROR(corruption_detected);
+ /* check */
+ endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4);
+ if (!endSignal) return ERROR(corruption_detected);
- /* decoded size */
- return dstSize;
+ /* decoded size */
+ return dstSize;
+ }
}
@@ -3150,14 +3156,13 @@ static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState)
litLength = FSEv05_peakSymbol(&(seqState->stateLL));
prevOffset = litLength ? seq->offset : seqState->prevOffset;
if (litLength == MaxLL) {
- U32 add = *dumps++;
+ const U32 add = *dumps++;
if (add < 255) litLength += add;
- else {
- litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
+ else if (dumps + 3 <= de) {
+ litLength = MEM_readLE24(dumps);
if (litLength&1) litLength>>=1, dumps += 3;
else litLength = (U16)(litLength)>>1, dumps += 2;
}
- if (dumps > de) { litLength = MaxLL+255; } /* late correction, to avoid using uninitialized memory */
if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
}
@@ -3184,14 +3189,13 @@ static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState)
/* MatchLength */
matchLength = FSEv05_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML) {
- U32 add = *dumps++;
+ const U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add;
- else {
- matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
+ else if (dumps + 3 <= de) {
+ matchLength = MEM_readLE24(dumps);
if (matchLength&1) matchLength>>=1, dumps += 3;
else matchLength = (U16)(matchLength)>>1, dumps += 2;
}
- if (dumps > de) { matchLength = MaxML+255; } /* late correction, to avoid using uninitialized memory */
if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
}
matchLength += MINMATCH;
diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c
index a695cbb8a6dde..f907a3a712261 100644
--- a/lib/legacy/zstd_v06.c
+++ b/lib/legacy/zstd_v06.c
@@ -3242,14 +3242,12 @@ static size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
}
/* FSE table descriptors */
+ if (ip + 4 > iend) return ERROR(srcSize_wrong); /* min : header byte + all 3 are "raw", hence no header, but at least xxLog bits per type */
{ U32 const LLtype = *ip >> 6;
U32 const Offtype = (*ip >> 4) & 3;
U32 const MLtype = (*ip >> 2) & 3;
ip++;
- /* check */
- if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
-
/* Build DTables */
{ size_t const bhSize = ZSTDv06_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
if (ZSTDv06_isError(bhSize)) return ERROR(corruption_detected);
@@ -3672,7 +3670,7 @@ void ZSTDv06_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cS
blockProperties_t blockProperties = { bt_compressed, 0 };
/* Frame Header */
- { size_t const frameHeaderSize = ZSTDv06_frameHeaderSize(src, ZSTDv06_frameHeaderSize_min);
+ { size_t const frameHeaderSize = ZSTDv06_frameHeaderSize(src, srcSize);
if (ZSTDv06_isError(frameHeaderSize)) {
ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, frameHeaderSize);
return;
diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c
index 6b9488931f35c..a83ddc9a68b0a 100644
--- a/lib/legacy/zstd_v07.c
+++ b/lib/legacy/zstd_v07.c
@@ -3470,14 +3470,12 @@ static size_t ZSTDv07_decodeSeqHeaders(int* nbSeqPtr,
}
/* FSE table descriptors */
+ if (ip + 4 > iend) return ERROR(srcSize_wrong); /* min : header byte + all 3 are "raw", hence no header, but at least xxLog bits per type */
{ U32 const LLtype = *ip >> 6;
U32 const OFtype = (*ip >> 4) & 3;
U32 const MLtype = (*ip >> 2) & 3;
ip++;
- /* check */
- if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
-
/* Build DTables */
{ size_t const llhSize = ZSTDv07_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
if (ZSTDv07_isError(llhSize)) return ERROR(corruption_detected);
@@ -3918,7 +3916,7 @@ void ZSTDv07_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cS
}
/* Frame Header */
- { size_t const frameHeaderSize = ZSTDv07_frameHeaderSize(src, ZSTDv07_frameHeaderSize_min);
+ { size_t const frameHeaderSize = ZSTDv07_frameHeaderSize(src, srcSize);
if (ZSTDv07_isError(frameHeaderSize)) {
ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, frameHeaderSize);
return;