Fix : decoder issue in exceptionnal circumstances (dst buffer too small)
This commit is contained in:
+14
-12
@@ -1405,7 +1405,7 @@ static size_t ZSTD_execSequence(BYTE* op, seq_t sequence, const BYTE** litPtr, B
|
|||||||
static const int dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; /* added */
|
static const int dec32table[] = {4, 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}; /* substracted */
|
||||||
const BYTE* const ostart = op;
|
const BYTE* const ostart = op;
|
||||||
size_t litLength = sequence.litLength;
|
const size_t litLength = sequence.litLength;
|
||||||
BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
|
BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
|
||||||
const BYTE* const litEnd = *litPtr + litLength;
|
const BYTE* const litEnd = *litPtr + litLength;
|
||||||
|
|
||||||
@@ -1418,14 +1418,17 @@ static size_t ZSTD_execSequence(BYTE* op, seq_t sequence, const BYTE** litPtr, B
|
|||||||
else
|
else
|
||||||
ZSTD_wildcopy(op, *litPtr, litLength);
|
ZSTD_wildcopy(op, *litPtr, litLength);
|
||||||
op += litLength;
|
op += litLength;
|
||||||
*litPtr = litEnd;
|
*litPtr = litEnd; /* update for next sequence */
|
||||||
|
|
||||||
/* copy Match */
|
/* check : last match must be at a minimum distance of 8 from end of dest buffer */
|
||||||
|
if (oend-op < 8) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
||||||
|
|
||||||
|
/* copy Match */
|
||||||
{
|
{
|
||||||
const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */
|
|
||||||
size_t qutt=12;
|
|
||||||
U64 saved[2];
|
|
||||||
const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12);
|
const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12);
|
||||||
|
const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */
|
||||||
|
size_t qutt = 12;
|
||||||
|
U64 saved[2];
|
||||||
|
|
||||||
/* save beginning of literal sequence, in case of write overlap */
|
/* save beginning of literal sequence, in case of write overlap */
|
||||||
if (overlapRisk)
|
if (overlapRisk)
|
||||||
@@ -1445,27 +1448,26 @@ static size_t ZSTD_execSequence(BYTE* op, seq_t sequence, const BYTE** litPtr, B
|
|||||||
ZSTD_copy4(op+4, match);
|
ZSTD_copy4(op+4, match);
|
||||||
match -= dec64;
|
match -= dec64;
|
||||||
} else { ZSTD_copy8(op, match); }
|
} else { ZSTD_copy8(op, match); }
|
||||||
|
op += 8; match += 8;
|
||||||
|
|
||||||
if (endMatch > oend-12)
|
if (endMatch > oend-12)
|
||||||
{
|
{
|
||||||
if (op < oend-16)
|
if (op < oend-8)
|
||||||
{
|
{
|
||||||
ZSTD_wildcopy(op+8, match+8, (oend-8) - (op+8));
|
ZSTD_wildcopy(op, match, (oend-8) - op);
|
||||||
match += (oend-8) - op;
|
match += (oend-8) - op;
|
||||||
op = oend-8;
|
op = oend-8;
|
||||||
}
|
}
|
||||||
while (op<endMatch) *op++ = *match++;
|
while (op<endMatch) *op++ = *match++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ZSTD_wildcopy(op+8, match+8, sequence.matchLength-8); /* works even if matchLength < 8 */
|
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
||||||
|
|
||||||
op = endMatch;
|
|
||||||
|
|
||||||
/* restore, in case of overlap */
|
/* restore, in case of overlap */
|
||||||
if (overlapRisk) memcpy(endMatch, saved, qutt);
|
if (overlapRisk) memcpy(endMatch, saved, qutt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return endMatch-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user