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 7158584399
dev
Nick Terrell 2016-10-20 16:45:10 -07:00
parent 52c1bf93fe
commit ae1cb3b3d0
5 changed files with 6 additions and 6 deletions

View File

@ -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;
}
} }

View File

@ -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;
}
}

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }