From ae1cb3b3d07024618269b89e3421d828adfd34d9 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 20 Oct 2016 16:45:10 -0700 Subject: [PATCH] Fix small bug in ZSTD_execSequence() `memmove(op, match, sequence.matchLength)` is not the desired behavior. Overlap is allowed, and handled as if we did `*op++ = *match++`, which is not how `memmove()` handles overlap. Only triggered if both of the following conditions are met: * The match spans extDict & currentPrefixSegment * `oLitEnd <= oend_w < oLitEnd + length1 < oMatchEnd <= oend`. These two conditions imply that the block is less than 15 bytes long. This bug isn't triggered by the streaming API, because it allocates enough space for the window size + the block size, so there cannot be a match that is within 8 bytes of the end and overlaps with itself. It cannot be triggered by the block decompression API because all of the decompressed data is in the currentPrefixSegment. Introduced by commit 71585843998459e636f639165ff8a1ca9d161b62 --- lib/decompress/zstd_decompress.c | 2 +- lib/legacy/zstd_v04.c | 2 +- lib/legacy/zstd_v05.c | 4 ++-- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v07.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 00b069e9f..90c76faeb 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -880,7 +880,7 @@ size_t ZSTD_execSequence(BYTE* op, sequence.matchLength -= length1; match = base; if (op > oend_w) { - memmove(op, match, sequence.matchLength); + while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } } } diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 05e40aac5..a2332d933 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -3108,7 +3108,7 @@ static size_t ZSTD_execSequence(BYTE* op, sequence.matchLength -= length1; match = base; if (op > oend_8) { - memmove(op, match, sequence.matchLength); + while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } } diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index 3cb5bb4af..0de28c983 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -2036,7 +2036,7 @@ size_t HUFv05_decompress1X2_usingDTable( const void* dtPtr = DTable; const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr)+1; BITv05_DStream_t bitD; - + if (dstSize <= cSrcSize) return ERROR(dstSize_tooSmall); { size_t const errorCode = BITv05_initDStream(&bitD, cSrc, cSrcSize); if (HUFv05_isError(errorCode)) return errorCode; } @@ -3317,7 +3317,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, sequence.matchLength -= length1; match = base; if (op > oend_8) { - memmove(op, match, sequence.matchLength); + while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } } } diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 96a84d3e8..b1ff4be4a 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3467,7 +3467,7 @@ size_t ZSTDv06_execSequence(BYTE* op, sequence.matchLength -= length1; match = base; if (op > oend_8) { - memmove(op, match, sequence.matchLength); + while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } } } diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 62285238a..c679b97f2 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3691,7 +3691,7 @@ size_t ZSTDv07_execSequence(BYTE* op, sequence.matchLength -= length1; match = base; if (op > oend_w) { - memmove(op, match, sequence.matchLength); + while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } } } -- 2.47.2