summaryrefslogtreecommitdiffstats
path: root/tests/fuzzer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/fuzzer.c')
-rw-r--r--tests/fuzzer.c423
1 files changed, 226 insertions, 197 deletions
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 3128e6d..a5b5c93 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -50,6 +50,10 @@
#include <assert.h>
#include <limits.h> /* INT_MAX */
+#if defined(_AIX)
+# include <sys/mman.h> /* mmap */
+#endif
+
#define LZ4_DISABLE_DEPRECATE_WARNINGS /* LZ4_decompress_fast */
#define LZ4_STATIC_LINKING_ONLY
#include "lz4.h"
@@ -315,20 +319,21 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
void* const lowAddrBuffer = FUZ_createLowAddr(labSize);
void* const stateLZ4 = malloc((size_t)LZ4_sizeofState());
void* const stateLZ4HC = malloc((size_t)LZ4_sizeofStateHC());
- LZ4_stream_t LZ4dict;
- LZ4_streamHC_t LZ4dictHC;
+ LZ4_stream_t LZ4dictBody;
+ LZ4_streamHC_t* LZ4dictHC = LZ4_createStreamHC();
U32 coreRandState = seed;
clock_t const clockStart = clock();
clock_t const clockDuration = (clock_t)duration_s * CLOCKS_PER_SEC;
int result = 0;
unsigned cycleNb;
-# define FUZ_CHECKTEST(cond, ...) \
- if (cond) { \
- printf("Test %u : ", testNb); printf(__VA_ARGS__); \
- printf(" (seed %u, cycle %u) \n", seed, cycleNb); \
- goto _output_error; \
- }
+# define EXIT_MSG(...) { \
+ printf("Test %u : ", testNb); printf(__VA_ARGS__); \
+ printf(" (seed %u, cycle %u) \n", seed, cycleNb); \
+ exit(1); \
+}
+
+# define FUZ_CHECKTEST(cond, ...) { if (cond) { EXIT_MSG(__VA_ARGS__) } }
# define FUZ_DISPLAYTEST(...) { \
testNb++; \
@@ -341,12 +346,11 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
/* init */
- if(!CNBuffer || !compressedBuffer || !decodedBuffer) {
+ if(!CNBuffer || !compressedBuffer || !decodedBuffer || !LZ4dictHC) {
DISPLAY("Not enough memory to start fuzzer tests");
- goto _output_error;
+ exit(1);
}
- if ( LZ4_initStream(&LZ4dict, sizeof(LZ4dict)) == NULL) abort();
- if ( LZ4_initStreamHC(&LZ4dictHC, sizeof(LZ4dictHC)) == NULL) abort();
+ if ( LZ4_initStream(&LZ4dictBody, sizeof(LZ4dictBody)) == NULL) abort();
{ U32 randState = coreRandState ^ PRIME3;
FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState);
}
@@ -450,133 +454,126 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
/* Test compression HC */
FUZ_DISPLAYTEST("test LZ4_compress_HC()");
- ret = LZ4_compress_HC(block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_HC() failed");
- HCcompressedSize = ret;
+ HCcompressedSize = LZ4_compress_HC(block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
+ FUZ_CHECKTEST(HCcompressedSize==0, "LZ4_compress_HC() failed");
/* Test compression HC using external state */
FUZ_DISPLAYTEST("test LZ4_compress_HC_extStateHC()");
- ret = LZ4_compress_HC_extStateHC(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_HC_extStateHC() failed")
+ { int const r = LZ4_compress_HC_extStateHC(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
+ FUZ_CHECKTEST(r==0, "LZ4_compress_HC_extStateHC() failed")
+ }
/* Test compression HC using fast reset external state */
FUZ_DISPLAYTEST("test LZ4_compress_HC_extStateHC_fastReset()");
- ret = LZ4_compress_HC_extStateHC_fastReset(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_HC_extStateHC_fastReset() failed");
+ { int const r = LZ4_compress_HC_extStateHC_fastReset(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
+ FUZ_CHECKTEST(r==0, "LZ4_compress_HC_extStateHC_fastReset() failed");
+ }
/* Test compression using external state */
FUZ_DISPLAYTEST("test LZ4_compress_fast_extState()");
- ret = LZ4_compress_fast_extState(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_fast_extState() failed");
+ { int const r = LZ4_compress_fast_extState(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
+ FUZ_CHECKTEST(r==0, "LZ4_compress_fast_extState() failed"); }
/* Test compression using fast reset external state*/
FUZ_DISPLAYTEST();
- ret = LZ4_compress_fast_extState_fastReset(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_fast_extState_fastReset() failed");
+ { int const r = LZ4_compress_fast_extState_fastReset(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
+ FUZ_CHECKTEST(r==0, "LZ4_compress_fast_extState_fastReset() failed"); }
/* Test compression */
FUZ_DISPLAYTEST("test LZ4_compress_default()");
- ret = LZ4_compress_default(block, compressedBuffer, blockSize, (int)compressedBufferSize);
- FUZ_CHECKTEST(ret==0, "LZ4_compress_default() failed");
- compressedSize = ret;
+ compressedSize = LZ4_compress_default(block, compressedBuffer, blockSize, (int)compressedBufferSize);
+ FUZ_CHECKTEST(compressedSize<=0, "LZ4_compress_default() failed");
/* Decompression tests */
- /* Test decoding with output size exactly correct => must work */
- FUZ_DISPLAYTEST("LZ4_decompress_fast() with exact output buffer");
- ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize);
- FUZ_CHECKTEST(ret<0, "LZ4_decompress_fast failed despite correct space");
- FUZ_CHECKTEST(ret!=compressedSize, "LZ4_decompress_fast failed : did not fully read compressed data");
- { U32 const crcCheck = XXH32(decodedBuffer, blockSize, 0);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast corrupted decoded data");
- }
+ /* Test decompress_fast() with input buffer size exactly correct => must not read out of bound */
+ { char* const cBuffer_exact = (char*)malloc((size_t)compressedSize);
+ assert(cBuffer_exact != NULL);
+ assert(compressedSize <= (int)compressedBufferSize);
+ memcpy(cBuffer_exact, compressedBuffer, compressedSize);
+
+ /* Test decoding with output size exactly correct => must work */
+ FUZ_DISPLAYTEST("LZ4_decompress_fast() with exact output buffer");
+ { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize);
+ FUZ_CHECKTEST(r<0, "LZ4_decompress_fast failed despite correct space");
+ FUZ_CHECKTEST(r!=compressedSize, "LZ4_decompress_fast failed : did not fully read compressed data");
+ }
+ { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
+ FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast corrupted decoded data");
+ }
- /* Test decoding with one byte missing => must fail */
- FUZ_DISPLAYTEST("LZ4_decompress_fast() with output buffer 1-byte too short");
- decodedBuffer[blockSize-1] = 0;
- ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize-1);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small");
- FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast overrun specified output buffer");
+ /* Test decoding with one byte missing => must fail */
+ FUZ_DISPLAYTEST("LZ4_decompress_fast() with output buffer 1-byte too short");
+ decodedBuffer[blockSize-1] = 0;
+ { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize-1);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small");
+ }
+ FUZ_CHECKTEST(decodedBuffer[blockSize-1]!=0, "LZ4_decompress_fast overrun specified output buffer");
- /* Test decoding with one byte too much => must fail */
- FUZ_DISPLAYTEST();
- ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize+1);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large");
+ /* Test decoding with one byte too much => must fail */
+ FUZ_DISPLAYTEST();
+ { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize+1);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large");
+ }
- /* Test decoding with empty input */
- FUZ_DISPLAYTEST("LZ4_decompress_safe() with empty input");
- LZ4_decompress_safe(compressedBuffer, decodedBuffer, 0, blockSize);
+ /* Test decoding with output size exactly what's necessary => must work */
+ FUZ_DISPLAYTEST();
+ decodedBuffer[blockSize] = 0;
+ { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize);
+ FUZ_CHECKTEST(r<0, "LZ4_decompress_safe failed despite sufficient space");
+ FUZ_CHECKTEST(r!=blockSize, "LZ4_decompress_safe did not regenerate original data");
+ }
+ FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
+ { U32 const crcCheck = XXH32(decodedBuffer, blockSize, 0);
+ FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
+ }
- /* Test decoding with a one byte input */
- FUZ_DISPLAYTEST("LZ4_decompress_safe() with one byte input");
- { char const tmp = (char)0xFF;
- LZ4_decompress_safe(&tmp, decodedBuffer, 1, blockSize);
- }
+ /* Test decoding with more than enough output size => must work */
+ FUZ_DISPLAYTEST();
+ decodedBuffer[blockSize] = 0;
+ decodedBuffer[blockSize+1] = 0;
+ { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize+1);
+ FUZ_CHECKTEST(r<0, "LZ4_decompress_safe failed despite amply sufficient space");
+ FUZ_CHECKTEST(r!=blockSize, "LZ4_decompress_safe did not regenerate original data");
+ }
+ FUZ_CHECKTEST(decodedBuffer[blockSize+1], "LZ4_decompress_safe overrun specified output buffer size");
+ { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
+ FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
+ }
- /* Test decoding shortcut edge case */
- FUZ_DISPLAYTEST("LZ4_decompress_safe() with shortcut edge case");
- { char tmp[17];
- /* 14 bytes of literals, followed by a 14 byte match.
- * Should not read beyond the end of the buffer.
- * See https://github.com/lz4/lz4/issues/508. */
- *tmp = (char)0xEE;
- memset(tmp + 1, 0, 14);
- tmp[15] = 14;
- tmp[16] = 0;
- ret = LZ4_decompress_safe(tmp, decodedBuffer, sizeof(tmp), blockSize);
- FUZ_CHECKTEST(ret >= 0, "LZ4_decompress_safe() should fail");
- }
+ /* Test decoding with output size being one byte too short => must fail */
+ FUZ_DISPLAYTEST();
+ decodedBuffer[blockSize-1] = 0;
+ { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize-1);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short");
+ }
+ FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe overrun specified output buffer size");
+ /* Test decoding with output size being 10 bytes too short => must fail */
+ FUZ_DISPLAYTEST();
+ if (blockSize>10) {
+ decodedBuffer[blockSize-10] = 0;
+ { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize-10);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to Output Size being 10 bytes too short");
+ }
+ FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe overrun specified output buffer size");
+ }
- /* Test decoding with output size exactly what's necessary => must work */
- FUZ_DISPLAYTEST();
- decodedBuffer[blockSize] = 0;
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize);
- FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite sufficient space");
- FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data");
- FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
- { U32 const crcCheck = XXH32(decodedBuffer, blockSize, 0);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
+ free(cBuffer_exact);
}
- // Test decoding with more than enough output size => must work
+ /* Test decoding with input size being one byte too short => must fail */
FUZ_DISPLAYTEST();
- decodedBuffer[blockSize] = 0;
- decodedBuffer[blockSize+1] = 0;
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize+1);
- FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite amply sufficient space");
- FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data");
- FUZ_CHECKTEST(decodedBuffer[blockSize+1], "LZ4_decompress_safe overrun specified output buffer size");
- { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
+ { int const r = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize-1, blockSize);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short (blockSize=%i, ret=%i, compressedSize=%i)", blockSize, ret, compressedSize);
}
- // Test decoding with output size being one byte too short => must fail
- FUZ_DISPLAYTEST();
- decodedBuffer[blockSize-1] = 0;
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-1);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short");
- FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe overrun specified output buffer size");
-
- // Test decoding with output size being 10 bytes too short => must fail
- FUZ_DISPLAYTEST();
- if (blockSize>10) {
- decodedBuffer[blockSize-10] = 0;
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-10);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being 10 bytes too short");
- FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe overrun specified output buffer size");
- }
-
- // Test decoding with input size being one byte too short => must fail
- FUZ_DISPLAYTEST();
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize-1, blockSize);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short (blockSize=%i, ret=%i, compressedSize=%i)", blockSize, ret, compressedSize);
-
- // Test decoding with input size being one byte too large => must fail
+ /* Test decoding with input size being one byte too large => must fail */
FUZ_DISPLAYTEST();
decodedBuffer[blockSize] = 0;
- ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize+1, blockSize);
- FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being too large");
+ { int const r = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize+1, blockSize);
+ FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to input size being too large");
+ }
FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
/* Test partial decoding => must work */
@@ -654,8 +651,10 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer+dictSize, blockSize, decodedBuffer, dictSize);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
{ U32 const crcCheck = XXH32(decodedBuffer+dictSize, (size_t)blockSize, 0);
- if (crcCheck!=crcOrig) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ if (crcCheck!=crcOrig) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ }
}
FUZ_DISPLAYTEST("test LZ4_decompress_safe_usingDict()");
@@ -669,20 +668,20 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_DISPLAYTEST("test LZ4_compress_fast_continue(), with non-contiguous dictionary");
dict -= (size_t)(FUZ_rand(&randState) & 0xF) + 1; /* create space, so now dictionary is an ExtDict */
if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
- LZ4_loadDict(&LZ4dict, dict, dictSize);
- blockContinueCompressedSize = LZ4_compress_fast_continue(&LZ4dict, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
+ LZ4_loadDict(&LZ4dictBody, dict, dictSize);
+ blockContinueCompressedSize = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_fast_continue failed");
FUZ_DISPLAYTEST("test LZ4_compress_fast_continue() with dictionary but with an output buffer too short by one byte");
- LZ4_loadDict(&LZ4dict, dict, dictSize);
- ret = LZ4_compress_fast_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize-1, 1);
+ LZ4_loadDict(&LZ4dictBody, dict, dictSize);
+ ret = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, blockContinueCompressedSize-1, 1);
FUZ_CHECKTEST(ret>0, "LZ4_compress_fast_continue using ExtDict should fail : one missing byte for output buffer : %i written, %i buffer", ret, blockContinueCompressedSize);
FUZ_DISPLAYTEST("test LZ4_compress_fast_continue() with dictionary loaded with LZ4_loadDict()");
DISPLAYLEVEL(5, " compress %i bytes from buffer(%p) into dst(%p) using dict(%p) of size %i \n",
blockSize, (const void *)block, (void *)decodedBuffer, (const void *)dict, dictSize);
- LZ4_loadDict(&LZ4dict, dict, dictSize);
- ret = LZ4_compress_fast_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
+ LZ4_loadDict(&LZ4dictBody, dict, dictSize);
+ ret = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue should work : enough size available within output buffer");
@@ -694,9 +693,11 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize, dict, dictSize);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
- { U32 const crcCheck = XXH32(decodedBuffer, blockSize, 0);
- if (crcCheck!=crcOrig) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
+ if (crcCheck!=crcOrig) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ }
}
FUZ_DISPLAYTEST();
@@ -736,15 +737,15 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
U32 expectedCrc;
FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_loadDict()");
- LZ4_loadDict(&LZ4dict, dict, dictSize);
- expectedSize = LZ4_compress_fast_continue(&LZ4dict, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
+ LZ4_loadDict(&LZ4dictBody, dict, dictSize);
+ expectedSize = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
FUZ_CHECKTEST(expectedSize<=0, "LZ4_compress_fast_continue reference compression for extDictCtx should have succeeded");
expectedCrc = XXH32(compressedBuffer, expectedSize, 0);
FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_attach_dictionary()");
- LZ4_loadDict(&LZ4dict, dict, dictSize);
+ LZ4_loadDict(&LZ4dictBody, dict, dictSize);
LZ4_initStream(&LZ4_stream, sizeof(LZ4_stream));
- LZ4_attach_dictionary(&LZ4_stream, &LZ4dict);
+ LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
blockContinueCompressedSize = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_fast_continue using extDictCtx failed");
FUZ_CHECKTEST(LZ4_stream.internal_donotuse.dirty, "context should be good");
@@ -759,14 +760,14 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_attach_dictionary(), but output buffer is 1 byte too short");
LZ4_resetStream_fast(&LZ4_stream);
- LZ4_attach_dictionary(&LZ4_stream, &LZ4dict);
+ LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize-1, 1);
FUZ_CHECKTEST(ret>0, "LZ4_compress_fast_continue using extDictCtx should fail : one missing byte for output buffer : %i written, %i buffer", ret, blockContinueCompressedSize);
/* note : context is no longer dirty after a failed compressed block */
FUZ_DISPLAYTEST();
LZ4_resetStream_fast(&LZ4_stream);
- LZ4_attach_dictionary(&LZ4_stream, &LZ4dict);
+ LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue using extDictCtx should work : enough size available within output buffer");
@@ -776,7 +777,7 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_DISPLAYTEST();
LZ4_resetStream_fast(&LZ4_stream);
- LZ4_attach_dictionary(&LZ4_stream, &LZ4dict);
+ LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue using extDictCtx with re-used context should work : enough size available within output buffer");
@@ -792,8 +793,10 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
{ U32 const crcCheck = XXH32(decodedBuffer, blockSize, 0);
- if (crcCheck!=crcOrig) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ if (crcCheck!=crcOrig) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
+ }
}
FUZ_DISPLAYTEST();
@@ -830,24 +833,24 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_DISPLAYTEST("LZ4_compress_HC_continue with an external dictionary");
dict -= (FUZ_rand(&randState) & 7); /* even bigger separation */
if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- LZ4_setCompressionLevel (&LZ4dictHC, compressionLevel);
- blockContinueCompressedSize = LZ4_compress_HC_continue(&LZ4dictHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
+ LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
+ LZ4_setCompressionLevel (LZ4dictHC, compressionLevel);
+ blockContinueCompressedSize = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue failed");
- FUZ_CHECKTEST(LZ4dictHC.internal_donotuse.dirty, "Context should be clean");
+ FUZ_CHECKTEST(LZ4dictHC->internal_donotuse.dirty, "Context should be clean");
FUZ_DISPLAYTEST("LZ4_compress_HC_continue with same external dictionary, but output buffer 1 byte too short");
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- ret = LZ4_compress_HC_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
+ LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
+ ret = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
FUZ_CHECKTEST(ret>0, "LZ4_compress_HC_continue using ExtDict should fail : one missing byte for output buffer (expected %i, but result=%i)", blockContinueCompressedSize, ret);
/* note : context is no longer dirty after a failed compressed block */
FUZ_DISPLAYTEST("LZ4_compress_HC_continue with same external dictionary, and output buffer exactly the right size");
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- ret = LZ4_compress_HC_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
+ LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
+ ret = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue size is different : ret(%i) != expected(%i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue should work : enough size available within output buffer");
- FUZ_CHECKTEST(LZ4dictHC.internal_donotuse.dirty, "Context should be clean");
+ FUZ_CHECKTEST(LZ4dictHC->internal_donotuse.dirty, "Context should be clean");
FUZ_DISPLAYTEST();
decodedBuffer[blockSize] = 0;
@@ -855,45 +858,46 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
{ U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
- if (crcCheck!=crcOrig) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
- }
+ if (crcCheck!=crcOrig) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
+ } }
/* Compress HC using external dictionary stream */
FUZ_DISPLAYTEST();
- {
- LZ4_streamHC_t LZ4_streamHC;
- LZ4_initStreamHC(&LZ4_streamHC, sizeof(LZ4_streamHC));
+ { LZ4_streamHC_t* const LZ4_streamHC = LZ4_createStreamHC();
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- LZ4_attach_HC_dictionary(&LZ4_streamHC, &LZ4dictHC);
- LZ4_setCompressionLevel (&LZ4_streamHC, compressionLevel);
- blockContinueCompressedSize = LZ4_compress_HC_continue(&LZ4_streamHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
+ LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
+ LZ4_attach_HC_dictionary(LZ4_streamHC, LZ4dictHC);
+ LZ4_setCompressionLevel (LZ4_streamHC, compressionLevel);
+ blockContinueCompressedSize = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue with ExtDictCtx failed");
- FUZ_CHECKTEST(LZ4_streamHC.internal_donotuse.dirty, "Context should be clean");
+ FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
FUZ_DISPLAYTEST();
- LZ4_resetStreamHC_fast (&LZ4_streamHC, compressionLevel);
- LZ4_attach_HC_dictionary(&LZ4_streamHC, &LZ4dictHC);
- ret = LZ4_compress_HC_continue(&LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
+ LZ4_resetStreamHC_fast (LZ4_streamHC, compressionLevel);
+ LZ4_attach_HC_dictionary(LZ4_streamHC, LZ4dictHC);
+ ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
FUZ_CHECKTEST(ret>0, "LZ4_compress_HC_continue using ExtDictCtx should fail : one missing byte for output buffer (%i != %i)", ret, blockContinueCompressedSize);
/* note : context is no longer dirty after a failed compressed block */
FUZ_DISPLAYTEST();
- LZ4_resetStreamHC_fast (&LZ4_streamHC, compressionLevel);
- LZ4_attach_HC_dictionary(&LZ4_streamHC, &LZ4dictHC);
- ret = LZ4_compress_HC_continue(&LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
+ LZ4_resetStreamHC_fast (LZ4_streamHC, compressionLevel);
+ LZ4_attach_HC_dictionary(LZ4_streamHC, LZ4dictHC);
+ ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue using ExtDictCtx size is different (%i != %i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue using ExtDictCtx should work : enough size available within output buffer");
- FUZ_CHECKTEST(LZ4_streamHC.internal_donotuse.dirty, "Context should be clean");
+ FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
FUZ_DISPLAYTEST();
- LZ4_resetStreamHC_fast (&LZ4_streamHC, compressionLevel);
- LZ4_attach_HC_dictionary(&LZ4_streamHC, &LZ4dictHC);
- ret = LZ4_compress_HC_continue(&LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
+ LZ4_resetStreamHC_fast (LZ4_streamHC, compressionLevel);
+ LZ4_attach_HC_dictionary(LZ4_streamHC, LZ4dictHC);
+ ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue using ExtDictCtx and fast reset size is different (%i != %i)", ret, blockContinueCompressedSize);
FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue using ExtDictCtx and fast reset should work : enough size available within output buffer");
- FUZ_CHECKTEST(LZ4_streamHC.internal_donotuse.dirty, "Context should be clean");
+ FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
+
+ LZ4_freeStreamHC(LZ4_streamHC);
}
FUZ_DISPLAYTEST();
@@ -902,18 +906,19 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
{ U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
- if (crcCheck!=crcOrig) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
- }
+ if (crcCheck!=crcOrig) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
+ } }
/* Compress HC continue destSize */
FUZ_DISPLAYTEST();
{ int const availableSpace = (int)(FUZ_rand(&randState) % blockSize) + 5;
int consumedSize = blockSize;
FUZ_DISPLAYTEST();
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- LZ4_setCompressionLevel(&LZ4dictHC, compressionLevel);
- blockContinueCompressedSize = LZ4_compress_HC_continue_destSize(&LZ4dictHC, block, compressedBuffer, &consumedSize, availableSpace);
+ LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
+ LZ4_setCompressionLevel(LZ4dictHC, compressionLevel);
+ blockContinueCompressedSize = LZ4_compress_HC_continue_destSize(LZ4dictHC, block, compressedBuffer, &consumedSize, availableSpace);
DISPLAYLEVEL(5, " LZ4_compress_HC_continue_destSize : compressed %6i/%6i into %6i/%6i at cLevel=%i\n", consumedSize, blockSize, blockContinueCompressedSize, availableSpace, compressionLevel);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue_destSize failed");
FUZ_CHECKTEST(blockContinueCompressedSize > availableSpace, "LZ4_compress_HC_continue_destSize write overflow");
@@ -926,9 +931,10 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
FUZ_CHECKTEST(decodedBuffer[consumedSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size")
{ U32 const crcSrc = XXH32(block, (size_t)consumedSize, 0);
U32 const crcDst = XXH32(decodedBuffer, (size_t)consumedSize, 0);
- if (crcSrc!=crcDst) FUZ_findDiff(block, decodedBuffer);
- FUZ_CHECKTEST(crcSrc!=crcDst, "LZ4_decompress_safe_usingDict corrupted decoded data");
- }
+ if (crcSrc!=crcDst) {
+ FUZ_findDiff(block, decodedBuffer);
+ EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
+ } }
}
/* ***** End of tests *** */
@@ -948,20 +954,14 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c
printf("ratio with dict: %0.3f%%\n", (double)ccbytes/bytes*100);
/* release memory */
- {
-_exit:
- free(CNBuffer);
- free(compressedBuffer);
- free(decodedBuffer);
- FUZ_freeLowAddr(lowAddrBuffer, labSize);
- free(stateLZ4);
- free(stateLZ4HC);
- return result;
-
-_output_error:
- result = 1;
- goto _exit;
- }
+ free(CNBuffer);
+ free(compressedBuffer);
+ free(decodedBuffer);
+ FUZ_freeLowAddr(lowAddrBuffer, labSize);
+ LZ4_freeStreamHC(LZ4dictHC);
+ free(stateLZ4);
+ free(stateLZ4HC);
+ return result;
}
@@ -974,29 +974,55 @@ static void FUZ_unitTests(int compressionLevel)
const unsigned testNb = 0;
const unsigned seed = 0;
const unsigned cycleNb= 0;
- char testInput[testInputSize];
- char testCompressed[testCompressedSize];
- size_t const testVerifySize = testInputSize;
- char testVerify[testInputSize];
- char ringBuffer[ringBufferSize];
+ char* testInput = (char*)malloc(testInputSize);
+ char* testCompressed = (char*)malloc(testCompressedSize);
+ char* testVerify = (char*)malloc(testInputSize);
+ char ringBuffer[ringBufferSize] = {0};
U32 randState = 1;
/* Init */
+ if (!testInput || !testCompressed || !testVerify) {
+ EXIT_MSG("not enough memory for FUZ_unitTests");
+ }
FUZ_fillCompressibleNoiseBuffer(testInput, testInputSize, 0.50, &randState);
/* 32-bits address space overflow test */
FUZ_AddressOverflow();
+ /* Test decoding with empty input */
+ DISPLAYLEVEL(3, "LZ4_decompress_safe() with empty input");
+ LZ4_decompress_safe(testCompressed, testVerify, 0, testInputSize);
+
+ /* Test decoding with a one byte input */
+ DISPLAYLEVEL(3, "LZ4_decompress_safe() with one byte input");
+ { char const tmp = (char)0xFF;
+ LZ4_decompress_safe(&tmp, testVerify, 1, testInputSize);
+ }
+
+ /* Test decoding shortcut edge case */
+ DISPLAYLEVEL(3, "LZ4_decompress_safe() with shortcut edge case");
+ { char tmp[17];
+ /* 14 bytes of literals, followed by a 14 byte match.
+ * Should not read beyond the end of the buffer.
+ * See https://github.com/lz4/lz4/issues/508. */
+ *tmp = (char)0xEE;
+ memset(tmp + 1, 0, 14);
+ tmp[15] = 14;
+ tmp[16] = 0;
+ { int const r = LZ4_decompress_safe(tmp, testVerify, sizeof(tmp), testInputSize);
+ FUZ_CHECKTEST(r >= 0, "LZ4_decompress_safe() should fail");
+ } }
+
/* LZ4 streaming tests */
- { LZ4_stream_t* statePtr;
- LZ4_stream_t streamingState;
+ { LZ4_stream_t streamingState;
U64 crcOrig;
int result;
/* Allocation test */
- statePtr = LZ4_createStream();
- FUZ_CHECKTEST(statePtr==NULL, "LZ4_createStream() allocation failed");
- LZ4_freeStream(statePtr);
+ { LZ4_stream_t* const statePtr = LZ4_createStream();
+ FUZ_CHECKTEST(statePtr==NULL, "LZ4_createStream() allocation failed");
+ LZ4_freeStream(statePtr);
+ }
/* simple compression test */
crcOrig = XXH64(testInput, testCompressedSize, 0);
@@ -1021,7 +1047,6 @@ static void FUZ_unitTests(int compressionLevel)
U32 rNext = 0;
U32 dNext = 0;
const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
- int compressedSize;
XXH64_reset(&xxhOrig, 0);
XXH64_reset(&xxhNewSafe, 0);
@@ -1031,6 +1056,7 @@ static void FUZ_unitTests(int compressionLevel)
LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
while (iNext + messageSize < testCompressedSize) {
+ int compressedSize;
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
@@ -1226,7 +1252,6 @@ static void FUZ_unitTests(int compressionLevel)
U32 rNext = 0;
U32 dNext = 0;
const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
- int compressedSize;
XXH64_reset(&xxhOrig, 0);
XXH64_reset(&xxhNewSafe, 0);
@@ -1236,6 +1261,7 @@ static void FUZ_unitTests(int compressionLevel)
LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
while (iNext + messageSize < testCompressedSize) {
+ int compressedSize;
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
@@ -1289,7 +1315,7 @@ static void FUZ_unitTests(int compressionLevel)
int dNext = 0;
int compressedSize;
- assert((size_t)dBufferSize * 2 + 1 < testVerifySize); /* space used by ringBufferSafe and ringBufferFast */
+ assert((size_t)dBufferSize * 2 + 1 < testInputSize); /* space used by ringBufferSafe and ringBufferFast */
XXH64_reset(&xxhOrig, 0);
XXH64_reset(&xxhNewSafe, 0);
XXH64_reset(&xxhNewFast, 0);
@@ -1301,7 +1327,7 @@ static void FUZ_unitTests(int compressionLevel)
/* first block */
messageSize = BSIZE1; /* note : we cheat a bit here, in theory no message should be > maxMessageSize. We just want to fill the decoding ring buffer once. */
- XXH64_update(&xxhOrig, testInput + iNext, messageSize);
+ XXH64_update(&xxhOrig, testInput + iNext, (size_t)messageSize);
crcOrig = XXH64_digest(&xxhOrig);
compressedSize = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
@@ -1374,10 +1400,13 @@ static void FUZ_unitTests(int compressionLevel)
}
}
+ /* clean up */
+ free(testInput);
+ free(testCompressed);
+ free(testVerify);
+
printf("All unit tests completed successfully compressionLevel=%d \n", compressionLevel);
return;
-_output_error:
- exit(1);
}