diff options
author | Conrad Meyer <cem@FreeBSD.org> | 2019-04-19 00:31:04 +0000 |
---|---|---|
committer | Conrad Meyer <cem@FreeBSD.org> | 2019-04-19 00:31:04 +0000 |
commit | 3f774a5e86430d45c78443d234a90ee54582564f (patch) | |
tree | 2ba6d7db94738038417c7384773435b12fbc5265 /lib/legacy/zstd_v06.c | |
parent | af73257b093737838d6086890c91f6ec13291ea7 (diff) |
Diffstat (limited to 'lib/legacy/zstd_v06.c')
-rw-r--r-- | lib/legacy/zstd_v06.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 60d8d6fd9a9b9..a695cbb8a6dde 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -506,6 +506,8 @@ typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t; #define FSEv06_ENCODING_STATIC 2 #define FSEv06_ENCODING_DYNAMIC 3 +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) + static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12, 13,14,15,16 }; @@ -3406,7 +3408,7 @@ static size_t ZSTDv06_execSequence(BYTE* op, if (sequence.offset < 8) { /* close range match, overlap */ static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ - static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ int const sub2 = dec64table[sequence.offset]; op[0] = match[0]; op[1] = match[1]; @@ -3654,36 +3656,62 @@ size_t ZSTDv06_decompress(void* dst, size_t dstCapacity, const void* src, size_t #endif } -size_t ZSTDv06_findFrameCompressedSize(const void* src, size_t srcSize) +/* ZSTD_errorFrameSizeInfoLegacy() : + assumes `cSize` and `dBound` are _not_ NULL */ +static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret) +{ + *cSize = ret; + *dBound = ZSTD_CONTENTSIZE_ERROR; +} + +void ZSTDv06_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; + size_t nbBlocks = 0; blockProperties_t blockProperties = { bt_compressed, 0 }; /* Frame Header */ { size_t const frameHeaderSize = ZSTDv06_frameHeaderSize(src, ZSTDv06_frameHeaderSize_min); - if (ZSTDv06_isError(frameHeaderSize)) return frameHeaderSize; - if (MEM_readLE32(src) != ZSTDv06_MAGICNUMBER) return ERROR(prefix_unknown); - if (srcSize < frameHeaderSize+ZSTDv06_blockHeaderSize) return ERROR(srcSize_wrong); + if (ZSTDv06_isError(frameHeaderSize)) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, frameHeaderSize); + return; + } + if (MEM_readLE32(src) != ZSTDv06_MAGICNUMBER) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown)); + return; + } + if (srcSize < frameHeaderSize+ZSTDv06_blockHeaderSize) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong)); + return; + } ip += frameHeaderSize; remainingSize -= frameHeaderSize; } /* Loop on each block */ while (1) { size_t const cBlockSize = ZSTDv06_getcBlockSize(ip, remainingSize, &blockProperties); - if (ZSTDv06_isError(cBlockSize)) return cBlockSize; + if (ZSTDv06_isError(cBlockSize)) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize); + return; + } ip += ZSTDv06_blockHeaderSize; remainingSize -= ZSTDv06_blockHeaderSize; - if (cBlockSize > remainingSize) return ERROR(srcSize_wrong); + if (cBlockSize > remainingSize) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong)); + return; + } if (cBlockSize == 0) break; /* bt_end */ ip += cBlockSize; remainingSize -= cBlockSize; + nbBlocks++; } - return ip - (const BYTE*)src; + *cSize = ip - (const BYTE*)src; + *dBound = nbBlocks * ZSTDv06_BLOCKSIZE_MAX; } /*_****************************** |