diff options
| author | Conrad Meyer <cem@FreeBSD.org> | 2019-08-08 15:30:49 +0000 |
|---|---|---|
| committer | Conrad Meyer <cem@FreeBSD.org> | 2019-08-08 15:30:49 +0000 |
| commit | fa94c7381af469a06d8f9077162c2cc5dee581cb (patch) | |
| tree | 1f6152d1ad6531de48efbb231bb91e55ba0ac2e4 /lib/legacy | |
| parent | 3f774a5e86430d45c78443d234a90ee54582564f (diff) | |
Diffstat (limited to 'lib/legacy')
| -rw-r--r-- | lib/legacy/zstd_legacy.h | 4 | ||||
| -rw-r--r-- | lib/legacy/zstd_v01.c | 196 | ||||
| -rw-r--r-- | lib/legacy/zstd_v02.c | 17 | ||||
| -rw-r--r-- | lib/legacy/zstd_v03.c | 17 | ||||
| -rw-r--r-- | lib/legacy/zstd_v04.c | 19 | ||||
| -rw-r--r-- | lib/legacy/zstd_v05.c | 172 | ||||
| -rw-r--r-- | lib/legacy/zstd_v06.c | 6 | ||||
| -rw-r--r-- | lib/legacy/zstd_v07.c | 6 |
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; |
