summaryrefslogtreecommitdiffstats
path: root/programs
diff options
context:
space:
mode:
authorYann Collet <yann.collet.73@gmail.com>2014-10-25 19:52:10 (GMT)
committerYann Collet <yann.collet.73@gmail.com>2014-10-25 19:52:10 (GMT)
commit2b421e97d4e7cfbefdc007bf30133b0de7e7e14e (patch)
tree7267d51213e3d1abaf853a80491db38f3d8f82c8 /programs
parente2c84118f52cefe48fd2f751e66ad3ecd904f7b9 (diff)
downloadlz4-2b421e97d4e7cfbefdc007bf30133b0de7e7e14e.zip
lz4-2b421e97d4e7cfbefdc007bf30133b0de7e7e14e.tar.gz
lz4-2b421e97d4e7cfbefdc007bf30133b0de7e7e14e.tar.bz2
HC streaming : support small ringbuffer scenarios
Diffstat (limited to 'programs')
-rwxr-xr-x[-rw-r--r--]programs/Makefile2
-rwxr-xr-xprograms/fuzzer.c411
2 files changed, 265 insertions, 148 deletions
diff --git a/programs/Makefile b/programs/Makefile
index 04694f2..e7e57a1 100644..100755
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -30,7 +30,7 @@
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
# ##########################################################################
-RELEASE=r123
+RELEASE=r124
DESTDIR?=
PREFIX ?= /usr
diff --git a/programs/fuzzer.c b/programs/fuzzer.c
index 225361b..07935fa 100755
--- a/programs/fuzzer.c
+++ b/programs/fuzzer.c
@@ -1,29 +1,29 @@
/*
- fuzzer.c - Fuzzer test tool for LZ4
- Copyright (C) Yann Collet 2012-2014
- GPL v2 License
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- You can contact the author at :
- - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
- - LZ4 source repository : http://code.google.com/p/lz4/
+fuzzer.c - Fuzzer test tool for LZ4
+Copyright (C) Yann Collet 2012-2014
+GPL v2 License
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+You can contact the author at :
+- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+- LZ4 source repository : http://code.google.com/p/lz4/
*/
/**************************************
- Remove Visual warning messages
+Remove Visual warning messages
**************************************/
#define _CRT_SECURE_NO_WARNINGS // fgets
#ifdef _MSC_VER /* Visual Studio */
@@ -34,7 +34,7 @@
/**************************************
- Includes
+Includes
**************************************/
#include <stdlib.h>
#include <stdio.h> // fgets, sscanf
@@ -46,26 +46,26 @@
/**************************************
- Basic Types
+Basic Types
**************************************/
#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */
# include <stdint.h>
- typedef uint8_t BYTE;
- typedef uint16_t U16;
- typedef uint32_t U32;
- typedef int32_t S32;
- typedef uint64_t U64;
+typedef uint8_t BYTE;
+typedef uint16_t U16;
+typedef uint32_t U32;
+typedef int32_t S32;
+typedef uint64_t U64;
#else
- typedef unsigned char BYTE;
- typedef unsigned short U16;
- typedef unsigned int U32;
- typedef signed int S32;
- typedef unsigned long long U64;
+typedef unsigned char BYTE;
+typedef unsigned short U16;
+typedef unsigned int U32;
+typedef signed int S32;
+typedef unsigned long long U64;
#endif
/**************************************
- Constants
+Constants
**************************************/
#ifndef LZ4_VERSION
# define LZ4_VERSION ""
@@ -87,7 +87,7 @@
/*****************************************
- Macros
+Macros
*****************************************/
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
@@ -97,7 +97,7 @@ static U32 g_time = 0;
/*********************************************************
- Fuzzer functions
+Fuzzer functions
*********************************************************/
static U32 FUZ_GetMilliStart(void)
{
@@ -178,88 +178,88 @@ static void FUZ_fillCompressibleNoiseBuffer(void* buffer, int bufferSize, double
#define BLOCKSIZE_I134 (32 MB)
static int FUZ_AddressOverflow(void)
{
- char* buffers[MAX_NB_BUFF_I134+1] = {0};
- int i, nbBuff=0;
- int highAddress = 0;
+ char* buffers[MAX_NB_BUFF_I134+1] = {0};
+ int i, nbBuff=0;
+ int highAddress = 0;
- printf("Overflow tests : ");
+ printf("Overflow tests : ");
- // Only possible in 32-bits
- if (sizeof(void*)==8)
- {
- printf("64 bits mode : no overflow \n");
- fflush(stdout);
- return 0;
- }
-
- buffers[0] = (char*)malloc(BLOCKSIZE_I134);
- buffers[1] = (char*)malloc(BLOCKSIZE_I134);
- if ((!buffers[0]) || (!buffers[1]))
- {
- printf("not enough memory for tests \n");
- return 0;
- }
- for (nbBuff=2; nbBuff < MAX_NB_BUFF_I134; nbBuff++)
- {
- printf("%3i \b\b\b\b", nbBuff);
- buffers[nbBuff] = (char*)malloc(BLOCKSIZE_I134);
- //printf("%08X ", (U32)(size_t)(buffers[nbBuff]));
- fflush(stdout);
-
- if (((size_t)buffers[nbBuff] > (size_t)0x80000000) && (!highAddress))
+ // Only possible in 32-bits
+ if (sizeof(void*)==8)
{
- printf("high address detected : ");
+ printf("64 bits mode : no overflow \n");
fflush(stdout);
- highAddress=1;
+ return 0;
}
- if (buffers[nbBuff]==NULL) goto _endOfTests;
+ buffers[0] = (char*)malloc(BLOCKSIZE_I134);
+ buffers[1] = (char*)malloc(BLOCKSIZE_I134);
+ if ((!buffers[0]) || (!buffers[1]))
{
- size_t sizeToGenerateOverflow = (size_t)(- ((size_t)buffers[nbBuff-1]) + 512);
- int nbOf255 = (int)((sizeToGenerateOverflow / 255) + 1);
- char* input = buffers[nbBuff-1];
- char* output = buffers[nbBuff];
- int r;
- input[0] = (char)0xF0; // Literal length overflow
- input[1] = (char)0xFF;
- input[2] = (char)0xFF;
- input[3] = (char)0xFF;
- for(i = 4; i <= nbOf255+4; i++) input[i] = (char)0xff;
- r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
- if (r>0) goto _overflowError;
- input[0] = (char)0x1F; // Match length overflow
- input[1] = (char)0x01;
- input[2] = (char)0x01;
- input[3] = (char)0x00;
- r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
- if (r>0) goto _overflowError;
-
- output = buffers[nbBuff-2]; // Reverse in/out pointer order
- input[0] = (char)0xF0; // Literal length overflow
- input[1] = (char)0xFF;
- input[2] = (char)0xFF;
- input[3] = (char)0xFF;
- r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
- if (r>0) goto _overflowError;
- input[0] = (char)0x1F; // Match length overflow
- input[1] = (char)0x01;
- input[2] = (char)0x01;
- input[3] = (char)0x00;
- r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
- if (r>0) goto _overflowError;
+ printf("not enough memory for tests \n");
+ return 0;
}
- }
+ for (nbBuff=2; nbBuff < MAX_NB_BUFF_I134; nbBuff++)
+ {
+ printf("%3i \b\b\b\b", nbBuff);
+ buffers[nbBuff] = (char*)malloc(BLOCKSIZE_I134);
+ //printf("%08X ", (U32)(size_t)(buffers[nbBuff]));
+ fflush(stdout);
+
+ if (((size_t)buffers[nbBuff] > (size_t)0x80000000) && (!highAddress))
+ {
+ printf("high address detected : ");
+ fflush(stdout);
+ highAddress=1;
+ }
+ if (buffers[nbBuff]==NULL) goto _endOfTests;
- nbBuff++;
+ {
+ size_t sizeToGenerateOverflow = (size_t)(- ((size_t)buffers[nbBuff-1]) + 512);
+ int nbOf255 = (int)((sizeToGenerateOverflow / 255) + 1);
+ char* input = buffers[nbBuff-1];
+ char* output = buffers[nbBuff];
+ int r;
+ input[0] = (char)0xF0; // Literal length overflow
+ input[1] = (char)0xFF;
+ input[2] = (char)0xFF;
+ input[3] = (char)0xFF;
+ for(i = 4; i <= nbOf255+4; i++) input[i] = (char)0xff;
+ r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
+ if (r>0) goto _overflowError;
+ input[0] = (char)0x1F; // Match length overflow
+ input[1] = (char)0x01;
+ input[2] = (char)0x01;
+ input[3] = (char)0x00;
+ r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
+ if (r>0) goto _overflowError;
+
+ output = buffers[nbBuff-2]; // Reverse in/out pointer order
+ input[0] = (char)0xF0; // Literal length overflow
+ input[1] = (char)0xFF;
+ input[2] = (char)0xFF;
+ input[3] = (char)0xFF;
+ r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
+ if (r>0) goto _overflowError;
+ input[0] = (char)0x1F; // Match length overflow
+ input[1] = (char)0x01;
+ input[2] = (char)0x01;
+ input[3] = (char)0x00;
+ r = LZ4_decompress_safe(input, output, nbOf255+64, BLOCKSIZE_I134);
+ if (r>0) goto _overflowError;
+ }
+ }
+
+ nbBuff++;
_endOfTests:
- for (i=0 ; i<nbBuff; i++) free(buffers[i]);
- if (!highAddress) printf("high address not possible \n");
- else printf("all overflows correctly detected \n");
- return 0;
+ for (i=0 ; i<nbBuff; i++) free(buffers[i]);
+ if (!highAddress) printf("high address not possible \n");
+ else printf("all overflows correctly detected \n");
+ return 0;
_overflowError:
- printf("Address space overflow error !! \n");
- exit(1);
+ printf("Address space overflow error !! \n");
+ exit(1);
}
@@ -285,15 +285,15 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
char* decodedBuffer;
# define FUZ_max LZ4_COMPRESSBOUND(LEN)
int ret;
- unsigned cycleNb;
+ 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; }
+ printf(" (seed %u, cycle %u) \n", seed, cycleNb); goto _output_error; }
# define FUZ_DISPLAYTEST { testNb++; g_displayLevel<3 ? 0 : printf("%2u\b\b", testNb); if (g_displayLevel==4) fflush(stdout); }
void* stateLZ4 = malloc(LZ4_sizeofState());
void* stateLZ4HC = malloc(LZ4_sizeofStateHC());
void* LZ4continue;
LZ4_stream_t LZ4dict;
- LZ4_streamHC_t LZ4dictHC;
+ LZ4_streamHC_t LZ4dictHC;
U32 crcOrig, crcCheck;
U32 coreRandState = seed;
U32 randState = coreRandState ^ PRIME3;
@@ -315,9 +315,9 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
if (0) // some problems related to dictionary re-use; in this case, enable this loop
{
- int dictSize, blockSize, blockStart;
- char* dict;
- char* block;
+ int dictSize, blockSize, blockStart;
+ char* dict;
+ char* block;
FUZ_displayUpdate(cycleNb);
randState = coreRandState ^ PRIME3;
blockSize = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE;
@@ -494,19 +494,19 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
FUZ_CHECKTEST(ret, "LZ4_compress_limitedOutput should have failed (output buffer too small by 1 byte)");
FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compress_limitedOutput overran output buffer")
- // Test HC compression with just one missing byte into output buffer => must fail
- FUZ_DISPLAYTEST;
+ // Test HC compression with just one missing byte into output buffer => must fail
+ FUZ_DISPLAYTEST;
compressedBuffer[HCcompressedSize-1] = 0;
ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize-1);
FUZ_CHECKTEST(ret, "LZ4_compressHC_limitedOutput should have failed (output buffer too small by 1 byte)");
FUZ_CHECKTEST(compressedBuffer[HCcompressedSize-1], "LZ4_compressHC_limitedOutput overran output buffer")
- /* Dictionary tests */
+ /* Dictionary tests */
- // Compress using dictionary
- FUZ_DISPLAYTEST;
+ // Compress using dictionary
+ FUZ_DISPLAYTEST;
LZ4continue = LZ4_create (dict);
- LZ4_compress_continue ((LZ4_stream_t*)LZ4continue, dict, compressedBuffer, dictSize); // Just to fill hash tables
+ LZ4_compress_continue ((LZ4_stream_t*)LZ4continue, dict, compressedBuffer, dictSize); // Just to fill hash tables
blockContinueCompressedSize = LZ4_compress_continue ((LZ4_stream_t*)LZ4continue, block, compressedBuffer, blockSize);
FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_continue failed");
free (LZ4continue);
@@ -557,7 +557,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
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")
- crcCheck = XXH32(decodedBuffer, blockSize, 0);
+ crcCheck = XXH32(decodedBuffer, blockSize, 0);
if (crcCheck!=crcOrig)
{
int i=0;
@@ -571,7 +571,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
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")
- crcCheck = XXH32(decodedBuffer, blockSize, 0);
+ crcCheck = XXH32(decodedBuffer, blockSize, 0);
FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
FUZ_DISPLAYTEST;
@@ -599,30 +599,30 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
}
// Compress HC using External dictionary
- FUZ_DISPLAYTEST;
- dict -= (FUZ_rand(&randState) & 7); // even bigger separation
- if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- blockContinueCompressedSize = LZ4_compressHC_continue(&LZ4dictHC, block, compressedBuffer, blockSize);
- FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compressHC_continue failed");
+ FUZ_DISPLAYTEST;
+ dict -= (FUZ_rand(&randState) & 7); // even bigger separation
+ if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
+ LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
+ blockContinueCompressedSize = LZ4_compressHC_continue(&LZ4dictHC, block, compressedBuffer, blockSize);
+ FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compressHC_continue failed");
- FUZ_DISPLAYTEST;
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- ret = LZ4_compressHC_limitedOutput_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
- FUZ_CHECKTEST(ret>0, "LZ4_compressHC_limitedOutput_continue using ExtDict should fail : one missing byte for output buffer");
+ FUZ_DISPLAYTEST;
+ LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
+ ret = LZ4_compressHC_limitedOutput_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
+ FUZ_CHECKTEST(ret>0, "LZ4_compressHC_limitedOutput_continue using ExtDict should fail : one missing byte for output buffer");
- FUZ_DISPLAYTEST;
- LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
- ret = LZ4_compressHC_limitedOutput_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
- FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
- FUZ_CHECKTEST(ret<=0, "LZ4_compress_limitedOutput_continue should work : enough size available within output buffer");
+ FUZ_DISPLAYTEST;
+ LZ4_loadDictHC(&LZ4dictHC, dict, dictSize);
+ ret = LZ4_compressHC_limitedOutput_continue(&LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
+ FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
+ FUZ_CHECKTEST(ret<=0, "LZ4_compress_limitedOutput_continue should work : enough size available within output buffer");
FUZ_DISPLAYTEST;
decodedBuffer[blockSize] = 0;
ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
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")
- crcCheck = XXH32(decodedBuffer, blockSize, 0);
+ crcCheck = XXH32(decodedBuffer, blockSize, 0);
if (crcCheck!=crcOrig)
{
int i=0;
@@ -632,8 +632,8 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
- // ***** End of tests *** //
- // Fill stats
+ // ***** End of tests *** //
+ // Fill stats
bytes += blockSize;
cbytes += compressedSize;
hcbytes += HCcompressedSize;
@@ -648,7 +648,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do
// unalloc
{
- int result = 0;
+ int result = 0;
_exit:
free(CNBuffer);
free(compressedBuffer);
@@ -663,8 +663,10 @@ _output_error:
}
}
+
#define testInputSize (128 KB)
#define testCompressedSize (64 KB)
+#define ringBufferSize (8 KB)
static void FUZ_unitTests(void)
{
@@ -674,7 +676,8 @@ static void FUZ_unitTests(void)
char testInput[testInputSize];
char testCompressed[testCompressedSize];
char testVerify[testInputSize];
- U32 randState = 0;
+ char ringBuffer[ringBufferSize];
+ U32 randState = 1;
// Init
FUZ_fillCompressibleNoiseBuffer(testInput, testInputSize, 0.50, &randState);
@@ -682,6 +685,75 @@ static void FUZ_unitTests(void)
// 32-bits address space overflow test
FUZ_AddressOverflow();
+ // LZ4 steraming tests
+ {
+ LZ4_stream_t* statePtr;
+ LZ4_stream_t streamingState;
+ U64 crcOrig;
+ U64 crcNew;
+ int result;
+
+ // Allocation test
+ statePtr = LZ4_createStream();
+ FUZ_CHECKTEST(statePtr==NULL, "LZ4_createStream() allocation failed");
+ LZ4_freeStream(statePtr);
+
+ // simple compression test
+ crcOrig = XXH64(testInput, testCompressedSize, 0);
+ LZ4_resetStream(&streamingState);
+ result = LZ4_compress_limitedOutput_continue(&streamingState, testInput, testCompressed, testCompressedSize, testCompressedSize-1);
+ FUZ_CHECKTEST(result==0, "LZ4_compress_limitedOutput_continue() compression failed");
+
+ result = LZ4_decompress_safe(testCompressed, testVerify, result, testCompressedSize);
+ FUZ_CHECKTEST(result!=(int)testCompressedSize, "LZ4_decompress_safe() decompression failed");
+ crcNew = XXH64(testVerify, testCompressedSize, 0);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption");
+
+ // ring buffer test
+ {
+ XXH64_state_t xxhOrig;
+ XXH64_state_t xxhNew;
+ LZ4_streamDecode_t decodeState;
+ const U32 maxMessageSizeLog = 10;
+ const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
+ U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+ U32 iNext = 0;
+ U32 rNext = 0;
+ U32 dNext = 0;
+ const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
+
+ XXH64_reset(&xxhOrig, 0);
+ XXH64_reset(&xxhNew, 0);
+ LZ4_resetStream(&streamingState);
+ LZ4_setStreamDecode(&decodeState, NULL, 0);
+
+ while (iNext + messageSize < testCompressedSize)
+ {
+ XXH64_update(&xxhOrig, testInput + iNext, messageSize);
+ crcOrig = XXH64_digest(&xxhOrig);
+
+ memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
+ result = LZ4_compress_limitedOutput_continue(&streamingState, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+ FUZ_CHECKTEST(result==0, "LZ4_compress_limitedOutput_continue() compression failed");
+
+ result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe() test failed");
+
+ XXH64_update(&xxhNew, testVerify + dNext, messageSize);
+ crcNew = crcOrig = XXH64_digest(&xxhNew);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption");
+
+ // prepare next message
+ iNext += messageSize;
+ rNext += messageSize;
+ dNext += messageSize;
+ messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+ if (rNext + messageSize > ringBufferSize) rNext = 0;
+ if (dNext + messageSize > dBufferSize) dNext = 0;
+ }
+ }
+ }
+
// LZ4 HC streaming tests
{
LZ4_streamHC_t* sp;
@@ -780,12 +852,12 @@ static void FUZ_unitTests(void)
FUZ_CHECKTEST(result!=segSize, "LZ4_decompress_safe_usingDict() dictionary decompression part %i failed", segNb);
XXH64_update(&crcNewState, dst, segSize);
crcNew = XXH64_digest(&crcNewState);
- if (crcOrig!=crcNew)
- {
- size_t c=0;
- while (dst[c] == testInput[segStart+c]) c++;
- DISPLAY("Bad decompression at %u / %u \n", (U32)c, (U32)segSize);
- }
+ if (crcOrig!=crcNew)
+ {
+ size_t c=0;
+ while (dst[c] == testInput[segStart+c]) c++;
+ DISPLAY("Bad decompression at %u / %u \n", (U32)c, (U32)segSize);
+ }
FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_usingDict() part %i corruption", segNb);
dict = dst;
@@ -799,6 +871,51 @@ static void FUZ_unitTests(void)
segSize = (FUZ_rand(&randState) & 8191);
}
}
+
+ // ring buffer test
+ {
+ XXH64_state_t xxhOrig;
+ XXH64_state_t xxhNew;
+ LZ4_streamDecode_t decodeState;
+ const U32 maxMessageSizeLog = 10;
+ const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
+ U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+ U32 iNext = 0;
+ U32 rNext = 0;
+ U32 dNext = 0;
+ const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
+
+ XXH64_reset(&xxhOrig, 0);
+ XXH64_reset(&xxhNew, 0);
+ LZ4_resetStreamHC(&sHC, 0);
+ LZ4_setStreamDecode(&decodeState, NULL, 0);
+
+ while (iNext + messageSize < testCompressedSize)
+ {
+ XXH64_update(&xxhOrig, testInput + iNext, messageSize);
+ crcOrig = XXH64_digest(&xxhOrig);
+
+ memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
+ result = LZ4_compressHC_limitedOutput_continue(&sHC, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+ FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
+
+ result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe() test failed");
+
+ XXH64_update(&xxhNew, testVerify + dNext, messageSize);
+ crcNew = crcOrig = XXH64_digest(&xxhNew);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption");
+
+ // prepare next message
+ iNext += messageSize;
+ rNext += messageSize;
+ dNext += messageSize;
+ messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+ if (rNext + messageSize > ringBufferSize) rNext = 0;
+ if (dNext + messageSize > dBufferSize) dNext = 0;
+ }
+ }
+
}
printf("All unit tests completed succesfully \n");