| 27094 | } |
| 27095 | |
| 27096 | HINT_INLINE |
| 27097 | size_t ZSTD_execSequence(BYTE* op, |
| 27098 | BYTE* const oend, seq_t sequence, |
| 27099 | const BYTE** litPtr, const BYTE* const litLimit, |
| 27100 | const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) |
| 27101 | { |
| 27102 | BYTE* const oLitEnd = op + sequence.litLength; |
| 27103 | size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
| 27104 | BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
| 27105 | BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */ |
| 27106 | const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
| 27107 | const BYTE* match = oLitEnd - sequence.offset; |
| 27108 | |
| 27109 | assert(op != NULL /* Precondition */); |
| 27110 | assert(oend_w < oend /* No underflow */); |
| 27111 | /* Handle edge cases in a slow path: |
| 27112 | * - Read beyond end of literals |
| 27113 | * - Match end is within WILDCOPY_OVERLIMIT of oend |
| 27114 | * - 32-bit mode and the match length overflows |
| 27115 | */ |
| 27116 | if (UNLIKELY( |
| 27117 | iLitEnd > litLimit || |
| 27118 | oMatchEnd > oend_w || |
| 27119 | (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) |
| 27120 | return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); |
| 27121 | |
| 27122 | /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ |
| 27123 | assert(op <= oLitEnd /* No overflow */); |
| 27124 | assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); |
| 27125 | assert(oMatchEnd <= oend /* No underflow */); |
| 27126 | assert(iLitEnd <= litLimit /* Literal length is in bounds */); |
| 27127 | assert(oLitEnd <= oend_w /* Can wildcopy literals */); |
| 27128 | assert(oMatchEnd <= oend_w /* Can wildcopy matches */); |
| 27129 | |
| 27130 | /* Copy Literals: |
| 27131 | * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. |
| 27132 | * We likely don't need the full 32-byte wildcopy. |
| 27133 | */ |
| 27134 | assert(WILDCOPY_OVERLENGTH >= 16); |
| 27135 | ZSTD_copy16(op, (*litPtr)); |
| 27136 | if (UNLIKELY(sequence.litLength > 16)) { |
| 27137 | ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap); |
| 27138 | } |
| 27139 | op = oLitEnd; |
| 27140 | *litPtr = iLitEnd; /* update for next sequence */ |
| 27141 | |
| 27142 | /* Copy Match */ |
| 27143 | if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { |
| 27144 | /* offset beyond prefix -> go into extDict */ |
| 27145 | RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); |
| 27146 | match = dictEnd + (match - prefixStart); |
| 27147 | if (match + sequence.matchLength <= dictEnd) { |
| 27148 | memmove(oLitEnd, match, sequence.matchLength); |
| 27149 | return sequenceLength; |
| 27150 | } |
| 27151 | /* span extDict & currentPrefixSegment */ |
| 27152 | { size_t const length1 = dictEnd - match; |
| 27153 | memmove(oLitEnd, match, length1); |
no test coverage detected