summaryrefslogtreecommitdiffstats
path: root/lib/lz4.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lz4.c')
-rw-r--r--lib/lz4.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index 1e938d0..978a957 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -1545,22 +1545,31 @@ LZ4_decompress_generic(
/* decode literal length */
if (length == RUN_MASK) {
- variable_length_error error = ok;
- length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
- if (error == initial_error) goto _output_error;
+ variable_length_error error = ok;
+ length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
+ if (error == initial_error) goto _output_error;
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */
if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */
- }
- /* copy literals */
- cpy = op+length;
- LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
- if ( ((endOnInput) && ((cpy>oend-FASTLOOP_SAFE_DISTANCE) || (ip+length>iend-(2+1+LASTLITERALS))) )
- || ((!endOnInput) && (cpy>oend-FASTLOOP_SAFE_DISTANCE)) )
- {
- goto safe_literal_copy;
+ /* copy literals */
+ cpy = op+length;
+ LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
+ if ( ((endOnInput) && ((cpy>oend-FASTLOOP_SAFE_DISTANCE) || (ip+length>iend-(2+1+LASTLITERALS))) )
+ || ((!endOnInput) && (cpy>oend-FASTLOOP_SAFE_DISTANCE)) )
+ {
+ goto safe_literal_copy;
+ }
+ LZ4_wildCopy16(op, ip, cpy);
+ ip += length; op = cpy;
} else {
- LZ4_wildCopy(op, ip, cpy); /* may overwrite up to WILDCOPYLENGTH beyond cpy */
+ cpy = op+length;
+ /* We don't need to check oend, since we check it once for each loop below */
+ if ( ((endOnInput) && (ip+16>iend-(2+1+LASTLITERALS))))
+ {
+ goto safe_literal_copy;
+ }
+ /* Literals can only be 14, but hope compilers optimize if we copy by a register size */
+ memcpy(op, ip, 16);
ip += length; op = cpy;
}