From e22bb8007432d42cda4c83daeb9e97ea15b7ef67 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 7 Sep 2018 18:22:01 -0700 Subject: fixed fuzzer test and removed one blind copy, since there is no more guarantee that at least 4 bytes are still available in output buffer --- lib/lz4.c | 10 ++++++---- tests/fuzzer.c | 7 ++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/lz4.c b/lib/lz4.c index 6febb90..dbda4f1 100644 --- a/lib/lz4.c +++ b/lib/lz4.c @@ -1398,8 +1398,7 @@ typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive; * Note that it is important for performance that this function really get inlined, * in order to remove useless branches during compilation optimization. */ -LZ4_FORCE_INLINE -int +LZ4_FORCE_INLINE int LZ4_decompress_generic( const char* const src, char* const dst, @@ -1432,7 +1431,7 @@ LZ4_decompress_generic( const BYTE* const shortiend = iend - (endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/; const BYTE* const shortoend = oend - (endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/; - DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i)", srcSize); + DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize); /* Special cases */ assert(src != NULL); @@ -1537,7 +1536,7 @@ LZ4_decompress_generic( _copy_match: if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ - LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ + // LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ /* note : no longer valid with partialDecoding, since there is no guarantee that at least 4 bytes are available */ if (length == ML_MASK) { unsigned s; @@ -1584,15 +1583,18 @@ _copy_match: /* specific : partial decode : does not respect end parsing restrictions */ assert(op<=oend); if (partialDecoding && (cpy > oend-12)) { + DEBUGLOG(2, "match copy close to the end"); size_t const mlen = MIN(length, (size_t)(oend-op)); const BYTE* const matchEnd = match + mlen; BYTE* const copyEnd = op + mlen; if (matchEnd > op) { /* overlap copy */ while (op < copyEnd) *op++ = *match++; } else { + DEBUGLOG(2, "let's memcopy %zu bytes (non overlapping)", mlen); memcpy(op, match, mlen); } op = copyEnd; + if (op==oend) break; continue; } diff --git a/tests/fuzzer.c b/tests/fuzzer.c index bdb7841..d6a5f51 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -582,11 +582,12 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c FUZ_DISPLAYTEST("test LZ4_decompress_safe_partial"); { size_t const missingBytes = FUZ_rand(&randState) % blockSize; int const targetSize = (int)(blockSize - missingBytes); - char const sentinel = compressedBuffer[targetSize] = block[targetSize] ^ 0x5A; + char const sentinel = decodedBuffer[targetSize] = block[targetSize] ^ 0x5A; + assert(decodedBuffer[targetSize] == sentinel); int const decResult = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, compressedSize, targetSize, blockSize); - FUZ_CHECKTEST(decResult<0, "LZ4_decompress_safe_partial failed despite valid input data"); + FUZ_CHECKTEST(decResult<0, "LZ4_decompress_safe_partial failed despite valid input data (error:%i)", decResult); FUZ_CHECKTEST(decResult != targetSize, "LZ4_decompress_safe_partial did not regenerated required amount of data (%i < %i <= %i)", decResult, targetSize, blockSize); - FUZ_CHECKTEST(compressedBuffer[targetSize] != sentinel, "LZ4_decompress_safe_partial overwrite beyond requested size (though %i <= %i <= %i)", decResult, targetSize, blockSize); + FUZ_CHECKTEST(decodedBuffer[targetSize] != sentinel, "LZ4_decompress_safe_partial overwrite beyond requested size (though %i <= %i <= %i)", decResult, targetSize, blockSize); } /* Test Compression with limited output size */ -- cgit v0.12