const BYTE* const litEnd = *litPtr + sequence.litLength;
const BYTE* match = oLitEnd - sequence.offset;
- /* check */
- if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
+ /* checks */
+ size_t const seqLength = sequence.litLength + sequence.matchLength;
+
+ if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
+ if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
+ /* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
+ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall);
+ if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected);
+
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
- if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */
+ if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
/* copy Literals */
- ZSTDv05_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
+ ZSTDv05_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
op = oLitEnd;
*litPtr = litEnd; /* update for next sequence */