Rizin
unix-like reverse engineering framework and cli tools
fuzzer.c File Reference
#include "platform.h"
#include "util.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <limits.h>
#include "lz4.h"
#include "lz4hc.h"
#include "xxhash.h"

Go to the source code of this file.

Macros

#define LZ4_DISABLE_DEPRECATE_WARNINGS   /* LZ4_decompress_fast */
 
#define LZ4_STATIC_LINKING_ONLY
 
#define LZ4_HC_STATIC_LINKING_ONLY
 
#define XXH_STATIC_LINKING_ONLY
 
#define NB_ATTEMPTS   (1<<16)
 
#define COMPRESSIBLE_NOISE_LENGTH   (1 << 21)
 
#define FUZ_MAX_BLOCK_SIZE   (1 << 17)
 
#define FUZ_MAX_DICT_SIZE   (1 << 15)
 
#define FUZ_COMPRESSIBILITY_DEFAULT   60
 
#define PRIME1   2654435761U
 
#define PRIME2   2246822519U
 
#define PRIME3   3266489917U
 
#define KB   *(1U<<10)
 
#define MB   *(1U<<20)
 
#define GB   *(1U<<30)
 
#define DISPLAY(...)   fprintf(stdout, __VA_ARGS__)
 
#define DISPLAYLEVEL(l, ...)   if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
 
#define MIN(a, b)   ( (a) < (b) ? (a) : (b) )
 
#define FUZ_RAND15BITS   ((FUZ_rand(seed) >> 3) & 32767)
 
#define FUZ_RANDLENGTH   ( ((FUZ_rand(seed) >> 7) & 3) ? (FUZ_rand(seed) % 15) : (FUZ_rand(seed) % 510) + 15)
 
#define MAX_NB_BUFF_I134   150
 
#define BLOCKSIZE_I134   (32 MB)
 
#define EXIT_MSG(...)
 
#define FUZ_CHECKTEST(cond, ...)   if (cond) { EXIT_MSG(__VA_ARGS__) }
 
#define FUZ_DISPLAYTEST(...)
 
#define testInputSize   (196 KB)
 
#define testCompressedSize   (130 KB)
 
#define ringBufferSize   (8 KB)
 
#define BSIZE1   (dBufferSize - (maxMessageSize-1))
 

Typedefs

typedef size_t uintptr_t
 

Functions

static clock_t FUZ_GetClockSpan (clock_t clockStart)
 
static void FUZ_displayUpdate (unsigned testNb)
 
static U32 FUZ_rotl32 (U32 u32, U32 nbBits)
 
static U32 FUZ_highbit32 (U32 v32)
 
static U32 FUZ_rand (U32 *src)
 
static void FUZ_fillCompressibleNoiseBuffer (void *buffer, size_t bufferSize, double proba, U32 *seed)
 
static int FUZ_AddressOverflow (void)
 
static void * FUZ_createLowAddr (size_t size)
 
static void FUZ_freeLowAddr (void *buffer, size_t size)
 
static void FUZ_findDiff (const void *buff1, const void *buff2)
 
static int FUZ_test (U32 seed, U32 nbCycles, const U32 startCycle, const double compressibility, U32 duration_s)
 
static void FUZ_unitTests (int compressionLevel)
 
static int FUZ_usage (const char *programName)
 
int main (int argc, const char **argv)
 

Variables

static int g_displayLevel = 2
 

Macro Definition Documentation

◆ BLOCKSIZE_I134

#define BLOCKSIZE_I134   (32 MB)

Definition at line 178 of file fuzzer.c.

◆ BSIZE1

#define BSIZE1   (dBufferSize - (maxMessageSize-1))

◆ COMPRESSIBLE_NOISE_LENGTH

#define COMPRESSIBLE_NOISE_LENGTH   (1 << 21)

Definition at line 78 of file fuzzer.c.

◆ DISPLAY

#define DISPLAY (   ...)    fprintf(stdout, __VA_ARGS__)

Definition at line 94 of file fuzzer.c.

◆ DISPLAYLEVEL

#define DISPLAYLEVEL (   l,
  ... 
)    if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }

Definition at line 95 of file fuzzer.c.

◆ EXIT_MSG

#define EXIT_MSG (   ...)
Value:
{ \
printf("Test %u : ", testNb); printf(__VA_ARGS__); \
printf(" (seed %u, cycle %u) \n", seed, cycleNb); \
exit(1); \
}
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93

◆ FUZ_CHECKTEST

#define FUZ_CHECKTEST (   cond,
  ... 
)    if (cond) { EXIT_MSG(__VA_ARGS__) }

◆ FUZ_COMPRESSIBILITY_DEFAULT

#define FUZ_COMPRESSIBILITY_DEFAULT   60

Definition at line 81 of file fuzzer.c.

◆ FUZ_DISPLAYTEST

#define FUZ_DISPLAYTEST (   ...)
Value:
{ \
testNb++; \
if (g_displayLevel>=4) { \
printf("\r%4u - %2u :", cycleNb, testNb); \
printf(" " __VA_ARGS__); \
printf(" "); \
fflush(stdout); \
} }
static int g_displayLevel
Definition: fuzzer.c:96

◆ FUZ_MAX_BLOCK_SIZE

#define FUZ_MAX_BLOCK_SIZE   (1 << 17)

Definition at line 79 of file fuzzer.c.

◆ FUZ_MAX_DICT_SIZE

#define FUZ_MAX_DICT_SIZE   (1 << 15)

Definition at line 80 of file fuzzer.c.

◆ FUZ_RAND15BITS

#define FUZ_RAND15BITS   ((FUZ_rand(seed) >> 3) & 32767)

Definition at line 144 of file fuzzer.c.

◆ FUZ_RANDLENGTH

#define FUZ_RANDLENGTH   ( ((FUZ_rand(seed) >> 7) & 3) ? (FUZ_rand(seed) % 15) : (FUZ_rand(seed) % 510) + 15)

Definition at line 145 of file fuzzer.c.

◆ GB

#define GB   *(1U<<30)

Definition at line 88 of file fuzzer.c.

◆ KB

#define KB   *(1U<<10)

Definition at line 86 of file fuzzer.c.

◆ LZ4_DISABLE_DEPRECATE_WARNINGS

#define LZ4_DISABLE_DEPRECATE_WARNINGS   /* LZ4_decompress_fast */

Definition at line 57 of file fuzzer.c.

◆ LZ4_HC_STATIC_LINKING_ONLY

#define LZ4_HC_STATIC_LINKING_ONLY

Definition at line 60 of file fuzzer.c.

◆ LZ4_STATIC_LINKING_ONLY

#define LZ4_STATIC_LINKING_ONLY

Definition at line 58 of file fuzzer.c.

◆ MAX_NB_BUFF_I134

#define MAX_NB_BUFF_I134   150

Definition at line 177 of file fuzzer.c.

◆ MB

#define MB   *(1U<<20)

Definition at line 87 of file fuzzer.c.

◆ MIN

#define MIN (   a,
  b 
)    ( (a) < (b) ? (a) : (b) )

Definition at line 98 of file fuzzer.c.

◆ NB_ATTEMPTS

#define NB_ATTEMPTS   (1<<16)

Definition at line 77 of file fuzzer.c.

◆ PRIME1

#define PRIME1   2654435761U

Definition at line 82 of file fuzzer.c.

◆ PRIME2

#define PRIME2   2246822519U

Definition at line 83 of file fuzzer.c.

◆ PRIME3

#define PRIME3   3266489917U

Definition at line 84 of file fuzzer.c.

◆ ringBufferSize

#define ringBufferSize   (8 KB)

Definition at line 1014 of file fuzzer.c.

◆ testCompressedSize

#define testCompressedSize   (130 KB)

Definition at line 1013 of file fuzzer.c.

◆ testInputSize

#define testInputSize   (196 KB)

Definition at line 1012 of file fuzzer.c.

◆ XXH_STATIC_LINKING_ONLY

#define XXH_STATIC_LINKING_ONLY

Definition at line 62 of file fuzzer.c.

Typedef Documentation

◆ uintptr_t

typedef size_t uintptr_t

Definition at line 70 of file fuzzer.c.

Function Documentation

◆ FUZ_AddressOverflow()

static int FUZ_AddressOverflow ( void  )
static

FUZ_AddressOverflow() : Aggressively pushes memory allocation limits, and generates patterns which create address space overflow. only possible in 32-bits mode

Definition at line 183 of file fuzzer.c.

184 {
185  char* buffers[MAX_NB_BUFF_I134+1];
186  int nbBuff=0;
187  int highAddress = 0;
188 
189  DISPLAY("Overflow tests : ");
190 
191  /* Only possible in 32-bits */
192  if (sizeof(void*)==8) {
193  DISPLAY("64 bits mode : no overflow \n");
194  fflush(stdout);
195  return 0;
196  }
197 
198  buffers[0] = (char*)malloc(BLOCKSIZE_I134);
199  buffers[1] = (char*)malloc(BLOCKSIZE_I134);
200  if ((!buffers[0]) || (!buffers[1])) {
201  free(buffers[0]); free(buffers[1]);
202  DISPLAY("not enough memory for tests \n");
203  return 0;
204  }
205 
206  for (nbBuff=2; nbBuff < MAX_NB_BUFF_I134; nbBuff++) {
207  DISPLAY("%3i \b\b\b\b", nbBuff); fflush(stdout);
208  buffers[nbBuff] = (char*)malloc(BLOCKSIZE_I134);
209  if (buffers[nbBuff]==NULL) goto _endOfTests;
210 
211  if (((uintptr_t)buffers[nbBuff] > (uintptr_t)0x80000000) && (!highAddress)) {
212  DISPLAY("high address detected : ");
213  fflush(stdout);
214  highAddress=1;
215  }
216 
217  { size_t const sizeToGenerateOverflow = (size_t)(- ((uintptr_t)buffers[nbBuff-1]) + 512);
218  int const nbOf255 = (int)((sizeToGenerateOverflow / 255) + 1);
219  char* const input = buffers[nbBuff-1];
220  char* output = buffers[nbBuff];
221  int r;
222  input[0] = (char)0xF0; /* Literal length overflow */
223  input[1] = (char)0xFF;
224  input[2] = (char)0xFF;
225  input[3] = (char)0xFF;
226  { int u; for(u = 4; u <= nbOf255+4; u++) input[u] = (char)0xff; }
228  if (r>0) { DISPLAY("LZ4_decompress_safe = %i \n", r); goto _overflowError; }
229  input[0] = (char)0x1F; /* Match length overflow */
230  input[1] = (char)0x01;
231  input[2] = (char)0x01;
232  input[3] = (char)0x00;
234  if (r>0) { DISPLAY("LZ4_decompress_safe = %i \n", r); goto _overflowError; }
235 
236  output = buffers[nbBuff-2]; /* Reverse in/out pointer order */
237  input[0] = (char)0xF0; /* Literal length overflow */
238  input[1] = (char)0xFF;
239  input[2] = (char)0xFF;
240  input[3] = (char)0xFF;
242  if (r>0) goto _overflowError;
243  input[0] = (char)0x1F; /* Match length overflow */
244  input[1] = (char)0x01;
245  input[2] = (char)0x01;
246  input[3] = (char)0x00;
248  if (r>0) goto _overflowError;
249  }
250  }
251 
252  nbBuff++;
253 _endOfTests:
254  { int i; for (i=0 ; i<nbBuff; i++) free(buffers[i]); }
255  if (!highAddress) DISPLAY("high address not possible \n");
256  else DISPLAY("all overflows correctly detected \n");
257  return 0;
258 
259 _overflowError:
260  DISPLAY("Address space overflow error !! \n");
261  exit(1);
262 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define BLOCKSIZE_I134
Definition: fuzzer.c:178
#define DISPLAY(...)
Definition: fuzzer.c:94
#define MAX_NB_BUFF_I134
Definition: fuzzer.c:177
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * malloc(size_t size)
Definition: malloc.c:123
LZ4_FORCE_O2 int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize)
Definition: lz4.c:2171
static int
Definition: sfsocketcall.h:114
int size_t
Definition: sftypes.h:40
_W64 unsigned int uintptr_t
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237

References BLOCKSIZE_I134, DISPLAY, test-lz4-list::exit, free(), i, input(), int, LZ4_decompress_safe(), malloc(), MAX_NB_BUFF_I134, NULL, output, and r.

Referenced by FUZ_unitTests().

◆ FUZ_createLowAddr()

static void* FUZ_createLowAddr ( size_t  size)
static

Definition at line 286 of file fuzzer.c.

287 {
288  return malloc(size);
289 }
voidpf void uLong size
Definition: ioapi.h:138

References malloc().

Referenced by FUZ_test().

◆ FUZ_displayUpdate()

static void FUZ_displayUpdate ( unsigned  testNb)
static

Definition at line 109 of file fuzzer.c.

110 {
111  static clock_t g_time = 0;
112  static const clock_t g_refreshRate = CLOCKS_PER_SEC / 5;
113  if ((FUZ_GetClockSpan(g_time) > g_refreshRate) || (g_displayLevel>=4)) {
114  g_time = clock();
115  DISPLAY("\r%5u ", testNb);
116  fflush(stdout);
117  }
118 }
static clock_t g_time
Definition: bench.c:260
static clock_t FUZ_GetClockSpan(clock_t clockStart)
Definition: fuzzer.c:104
int clock_t
Definition: sftypes.h:43

References DISPLAY, FUZ_GetClockSpan(), g_displayLevel, and g_time.

Referenced by FUZ_test().

◆ FUZ_fillCompressibleNoiseBuffer()

static void FUZ_fillCompressibleNoiseBuffer ( void *  buffer,
size_t  bufferSize,
double  proba,
U32 seed 
)
static

Definition at line 146 of file fuzzer.c.

147 {
148  BYTE* const BBuffer = (BYTE*)buffer;
149  size_t pos = 0;
150  U32 const P32 = (U32)(32768 * proba);
151 
152  /* First Bytes */
153  while (pos < 20)
154  BBuffer[pos++] = (BYTE)(FUZ_rand(seed));
155 
156  while (pos < bufferSize) {
157  /* Select : Literal (noise) or copy (within 64K) */
158  if (FUZ_RAND15BITS < P32) {
159  /* Copy (within 64K) */
160  size_t const length = (size_t)FUZ_RANDLENGTH + 4;
161  size_t const d = MIN(pos+length, bufferSize);
162  size_t match;
163  size_t offset = (size_t)FUZ_RAND15BITS + 1;
164  while (offset > pos) offset >>= 1;
165  match = pos - offset;
166  while (pos < d) BBuffer[pos++] = BBuffer[match++];
167  } else {
168  /* Literal (noise) */
169  size_t const length = FUZ_RANDLENGTH;
170  size_t const d = MIN(pos+length, bufferSize);
171  while (pos < d) BBuffer[pos++] = (BYTE)(FUZ_rand(seed) >> 5);
172  }
173  }
174 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
#define MIN(a, b)
Definition: fuzzer.c:98
#define FUZ_RANDLENGTH
Definition: fuzzer.c:145
#define FUZ_RAND15BITS
Definition: fuzzer.c:144
static U32 FUZ_rand(U32 *src)
Definition: fuzzer.c:133
unsigned char match[65280+2]
Definition: gun.c:165
voidpf uLong offset
Definition: ioapi.h:144
unsigned char BYTE
Definition: lz4.c:286
unsigned int U32
Definition: lz4.c:288
#define U32(val)
#define d(i)
Definition: sha256.c:44
Definition: buffer.h:15
Definition: engine.c:71
int pos
Definition: main.c:11

References d, FUZ_rand(), FUZ_RAND15BITS, FUZ_RANDLENGTH, length, match, MIN, pos, and U32.

Referenced by FUZ_test(), and FUZ_unitTests().

◆ FUZ_findDiff()

static void FUZ_findDiff ( const void *  buff1,
const void *  buff2 
)
static

FUZ_findDiff() : find the first different byte between buff1 and buff2. presumes buff1 != buff2. presumes a difference exists before end of either buffer. Typically invoked after a checksum mismatch.

Definition at line 306 of file fuzzer.c.

307 {
308  const BYTE* const b1 = (const BYTE*)buff1;
309  const BYTE* const b2 = (const BYTE*)buff2;
310  size_t u = 0;
311  while (b1[u]==b2[u]) u++;
312  DISPLAY("\nWrong Byte at position %u \n", (unsigned)u);
313 }

References b1, b2, and DISPLAY.

Referenced by FUZ_test(), and FUZ_unitTests().

◆ FUZ_freeLowAddr()

static void FUZ_freeLowAddr ( void *  buffer,
size_t  size 
)
static

Definition at line 291 of file fuzzer.c.

292 {
293  (void)size;
294  free(buffer);
295 }

References free().

Referenced by FUZ_test().

◆ FUZ_GetClockSpan()

static clock_t FUZ_GetClockSpan ( clock_t  clockStart)
static

Definition at line 104 of file fuzzer.c.

105 {
106  return clock() - clockStart; /* works even if overflow; max span ~ 30mn */
107 }

Referenced by FUZ_displayUpdate(), and FUZ_test().

◆ FUZ_highbit32()

static U32 FUZ_highbit32 ( U32  v32)
static

Definition at line 125 of file fuzzer.c.

126 {
127  unsigned nbBits = 0;
128  if (v32==0) return 0;
129  while (v32) { v32 >>= 1; nbBits++; }
130  return nbBits;
131 }

Referenced by FUZ_test().

◆ FUZ_rand()

static U32 FUZ_rand ( U32 src)
static

Definition at line 133 of file fuzzer.c.

134 {
135  U32 rand32 = *src;
136  rand32 *= PRIME1;
137  rand32 ^= PRIME2;
138  rand32 = FUZ_rotl32(rand32, 13);
139  *src = rand32;
140  return rand32;
141 }
lzma_index * src
Definition: index.h:567
#define PRIME2
Definition: fuzzer.c:83
static U32 FUZ_rotl32(U32 u32, U32 nbBits)
Definition: fuzzer.c:120
#define PRIME1
Definition: fuzzer.c:82

References FUZ_rotl32(), PRIME1, PRIME2, and src.

Referenced by FUZ_fillCompressibleNoiseBuffer(), FUZ_test(), and FUZ_unitTests().

◆ FUZ_rotl32()

static U32 FUZ_rotl32 ( U32  u32,
U32  nbBits 
)
static

Definition at line 120 of file fuzzer.c.

121 {
122  return ((u32 << nbBits) | (u32 >> (32 - nbBits)));
123 }

Referenced by FUZ_rand().

◆ FUZ_test()

static int FUZ_test ( U32  seed,
U32  nbCycles,
const U32  startCycle,
const double  compressibility,
U32  duration_s 
)
static

Definition at line 316 of file fuzzer.c.

317 {
318  unsigned long long bytes = 0;
319  unsigned long long cbytes = 0;
320  unsigned long long hcbytes = 0;
321  unsigned long long ccbytes = 0;
322  void* const CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
323  size_t const compressedBufferSize = (size_t)LZ4_compressBound(FUZ_MAX_BLOCK_SIZE);
324  char* const compressedBuffer = (char*)malloc(compressedBufferSize);
325  char* const decodedBuffer = (char*)malloc(FUZ_MAX_DICT_SIZE + FUZ_MAX_BLOCK_SIZE);
326  size_t const labSize = 96 KB;
327  void* const lowAddrBuffer = FUZ_createLowAddr(labSize);
328  void* const stateLZ4 = malloc((size_t)LZ4_sizeofState());
329  void* const stateLZ4HC = malloc((size_t)LZ4_sizeofStateHC());
330  LZ4_stream_t LZ4dictBody;
331  LZ4_streamHC_t* LZ4dictHC = LZ4_createStreamHC();
332  U32 coreRandState = seed;
333  clock_t const clockStart = clock();
334  clock_t const clockDuration = (clock_t)duration_s * CLOCKS_PER_SEC;
335  int result = 0;
336  unsigned cycleNb;
337 
338 # define EXIT_MSG(...) { \
339  printf("Test %u : ", testNb); printf(__VA_ARGS__); \
340  printf(" (seed %u, cycle %u) \n", seed, cycleNb); \
341  exit(1); \
342 }
343 
344 # define FUZ_CHECKTEST(cond, ...) if (cond) { EXIT_MSG(__VA_ARGS__) }
345 
346 # define FUZ_DISPLAYTEST(...) { \
347  testNb++; \
348  if (g_displayLevel>=4) { \
349  printf("\r%4u - %2u :", cycleNb, testNb); \
350  printf(" " __VA_ARGS__); \
351  printf(" "); \
352  fflush(stdout); \
353  } }
354 
355 
356  /* init */
357  if(!CNBuffer || !compressedBuffer || !decodedBuffer || !LZ4dictHC) {
358  DISPLAY("Not enough memory to start fuzzer tests");
359  exit(1);
360  }
361  if ( LZ4_initStream(&LZ4dictBody, sizeof(LZ4dictBody)) == NULL) abort();
362  { U32 randState = coreRandState ^ PRIME3;
363  FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState);
364  }
365 
366  /* move to startCycle */
367  for (cycleNb = 0; cycleNb < startCycle; cycleNb++)
368  (void) FUZ_rand(&coreRandState); /* sync coreRandState */
369 
370  /* Main test loop */
371  for (cycleNb = startCycle;
372  (cycleNb < nbCycles) || (FUZ_GetClockSpan(clockStart) < clockDuration);
373  cycleNb++) {
374  U32 testNb = 0;
375  U32 randState = FUZ_rand(&coreRandState) ^ PRIME3;
376  int const blockSize = (FUZ_rand(&randState) % (FUZ_MAX_BLOCK_SIZE-1)) + 1;
377  int const blockStart = (int)(FUZ_rand(&randState) % (U32)(COMPRESSIBLE_NOISE_LENGTH - blockSize - 1)) + 1;
378  int const dictSizeRand = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE;
379  int const dictSize = MIN(dictSizeRand, blockStart - 1);
380  int const compressionLevel = FUZ_rand(&randState) % (LZ4HC_CLEVEL_MAX+1);
381  const char* block = ((char*)CNBuffer) + blockStart;
382  const char* dict = block - dictSize;
383  int compressedSize, HCcompressedSize;
384  int blockContinueCompressedSize;
385  U32 const crcOrig = XXH32(block, (size_t)blockSize, 0);
386  int ret;
387 
388  FUZ_displayUpdate(cycleNb);
389 
390  /* Compression tests */
391  if ( ((FUZ_rand(&randState) & 63) == 2)
392  && ((size_t)blockSize < labSize) ) {
393  memcpy(lowAddrBuffer, block, blockSize);
394  block = (const char*)lowAddrBuffer;
395  }
396 
397  /* Test compression destSize */
398  FUZ_DISPLAYTEST("test LZ4_compress_destSize()");
399  { int cSize, srcSize = blockSize;
400  int const targetSize = srcSize * (int)((FUZ_rand(&randState) & 127)+1) >> 7;
401  char const endCheck = (char)(FUZ_rand(&randState) & 255);
402  compressedBuffer[targetSize] = endCheck;
403  cSize = LZ4_compress_destSize(block, compressedBuffer, &srcSize, targetSize);
404  FUZ_CHECKTEST(cSize > targetSize, "LZ4_compress_destSize() result larger than dst buffer !");
405  FUZ_CHECKTEST(compressedBuffer[targetSize] != endCheck, "LZ4_compress_destSize() overwrite dst buffer !");
406  FUZ_CHECKTEST(srcSize > blockSize, "LZ4_compress_destSize() read more than src buffer !");
407  DISPLAYLEVEL(5, "destSize : %7i/%7i; content%7i/%7i ", cSize, targetSize, srcSize, blockSize);
408  if (targetSize>0) {
409  /* check correctness */
410  U32 const crcBase = XXH32(block, (size_t)srcSize, 0);
411  char const canary = (char)(FUZ_rand(&randState) & 255);
412  FUZ_CHECKTEST((cSize==0), "LZ4_compress_destSize() compression failed");
413  FUZ_DISPLAYTEST();
414  decodedBuffer[srcSize] = canary;
415  { int const dSize = LZ4_decompress_safe(compressedBuffer, decodedBuffer, cSize, srcSize);
416  FUZ_CHECKTEST(dSize<0, "LZ4_decompress_safe() failed on data compressed by LZ4_compress_destSize");
417  FUZ_CHECKTEST(dSize!=srcSize, "LZ4_decompress_safe() failed : did not fully decompressed data");
418  }
419  FUZ_CHECKTEST(decodedBuffer[srcSize] != canary, "LZ4_decompress_safe() overwrite dst buffer !");
420  { U32 const crcDec = XXH32(decodedBuffer, (size_t)srcSize, 0);
421  FUZ_CHECKTEST(crcDec!=crcBase, "LZ4_decompress_safe() corrupted decoded data");
422  } }
423  DISPLAYLEVEL(5, " OK \n");
424  }
425 
426  /* Test compression HC destSize */
427  FUZ_DISPLAYTEST("test LZ4_compress_HC_destSize()");
428  { int cSize, srcSize = blockSize;
429  int const targetSize = srcSize * (int)((FUZ_rand(&randState) & 127)+1) >> 7;
430  char const endCheck = (char)(FUZ_rand(&randState) & 255);
431  void* const ctx = LZ4_createHC(block);
432  FUZ_CHECKTEST(ctx==NULL, "LZ4_createHC() allocation failed");
433  compressedBuffer[targetSize] = endCheck;
434  cSize = LZ4_compress_HC_destSize(ctx, block, compressedBuffer, &srcSize, targetSize, compressionLevel);
435  DISPLAYLEVEL(5, "LZ4_compress_HC_destSize(%i): destSize : %7i/%7i; content%7i/%7i ",
436  compressionLevel, cSize, targetSize, srcSize, blockSize);
437  LZ4_freeHC(ctx);
438  FUZ_CHECKTEST(cSize > targetSize, "LZ4_compress_HC_destSize() result larger than dst buffer !");
439  FUZ_CHECKTEST(compressedBuffer[targetSize] != endCheck, "LZ4_compress_HC_destSize() overwrite dst buffer !");
440  FUZ_CHECKTEST(srcSize > blockSize, "LZ4_compress_HC_destSize() fed more than src buffer !");
441  if (targetSize>0) {
442  /* check correctness */
443  U32 const crcBase = XXH32(block, (size_t)srcSize, 0);
444  char const canary = (char)(FUZ_rand(&randState) & 255);
445  FUZ_CHECKTEST((cSize==0), "LZ4_compress_HC_destSize() compression failed");
446  FUZ_DISPLAYTEST();
447  decodedBuffer[srcSize] = canary;
448  { int const dSize = LZ4_decompress_safe(compressedBuffer, decodedBuffer, cSize, srcSize);
449  FUZ_CHECKTEST(dSize<0, "LZ4_decompress_safe failed (%i) on data compressed by LZ4_compressHC_destSize", dSize);
450  FUZ_CHECKTEST(dSize!=srcSize, "LZ4_decompress_safe failed : decompressed %i bytes, was supposed to decompress %i bytes", dSize, srcSize);
451  }
452  FUZ_CHECKTEST(decodedBuffer[srcSize] != canary, "LZ4_decompress_safe overwrite dst buffer !");
453  { U32 const crcDec = XXH32(decodedBuffer, (size_t)srcSize, 0);
454  FUZ_CHECKTEST(crcDec!=crcBase, "LZ4_decompress_safe() corrupted decoded data");
455  } }
456  DISPLAYLEVEL(5, " OK \n");
457  }
458 
459  /* Test compression HC */
460  FUZ_DISPLAYTEST("test LZ4_compress_HC()");
461  HCcompressedSize = LZ4_compress_HC(block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
462  FUZ_CHECKTEST(HCcompressedSize==0, "LZ4_compress_HC() failed");
463 
464  /* Test compression HC using external state */
465  FUZ_DISPLAYTEST("test LZ4_compress_HC_extStateHC()");
466  { int const r = LZ4_compress_HC_extStateHC(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
467  FUZ_CHECKTEST(r==0, "LZ4_compress_HC_extStateHC() failed")
468  }
469 
470  /* Test compression HC using fast reset external state */
471  FUZ_DISPLAYTEST("test LZ4_compress_HC_extStateHC_fastReset()");
472  { int const r = LZ4_compress_HC_extStateHC_fastReset(stateLZ4HC, block, compressedBuffer, blockSize, (int)compressedBufferSize, compressionLevel);
473  FUZ_CHECKTEST(r==0, "LZ4_compress_HC_extStateHC_fastReset() failed");
474  }
475 
476  /* Test compression using external state */
477  FUZ_DISPLAYTEST("test LZ4_compress_fast_extState()");
478  { int const r = LZ4_compress_fast_extState(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
479  FUZ_CHECKTEST(r==0, "LZ4_compress_fast_extState() failed"); }
480 
481  /* Test compression using fast reset external state*/
482  FUZ_DISPLAYTEST();
483  { int const r = LZ4_compress_fast_extState_fastReset(stateLZ4, block, compressedBuffer, blockSize, (int)compressedBufferSize, 8);
484  FUZ_CHECKTEST(r==0, "LZ4_compress_fast_extState_fastReset() failed"); }
485 
486  /* Test compression */
487  FUZ_DISPLAYTEST("test LZ4_compress_default()");
488  compressedSize = LZ4_compress_default(block, compressedBuffer, blockSize, (int)compressedBufferSize);
489  FUZ_CHECKTEST(compressedSize<=0, "LZ4_compress_default() failed");
490 
491  /* Decompression tests */
492 
493  /* Test decompress_fast() with input buffer size exactly correct => must not read out of bound */
494  { char* const cBuffer_exact = (char*)malloc((size_t)compressedSize);
495  assert(cBuffer_exact != NULL);
496  assert(compressedSize <= (int)compressedBufferSize);
497  memcpy(cBuffer_exact, compressedBuffer, compressedSize);
498 
499  /* Test decoding with output size exactly correct => must work */
500  FUZ_DISPLAYTEST("LZ4_decompress_fast() with exact output buffer");
501  { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize);
502  FUZ_CHECKTEST(r<0, "LZ4_decompress_fast failed despite correct space");
503  FUZ_CHECKTEST(r!=compressedSize, "LZ4_decompress_fast failed : did not fully read compressed data");
504  }
505  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
506  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast corrupted decoded data");
507  }
508 
509  /* Test decoding with one byte missing => must fail */
510  FUZ_DISPLAYTEST("LZ4_decompress_fast() with output buffer 1-byte too short");
511  decodedBuffer[blockSize-1] = 0;
512  { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize-1);
513  FUZ_CHECKTEST(r>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small");
514  }
515  FUZ_CHECKTEST(decodedBuffer[blockSize-1]!=0, "LZ4_decompress_fast overrun specified output buffer");
516 
517  /* Test decoding with one byte too much => must fail */
518  FUZ_DISPLAYTEST();
519  { int const r = LZ4_decompress_fast(cBuffer_exact, decodedBuffer, blockSize+1);
520  FUZ_CHECKTEST(r>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large");
521  }
522 
523  /* Test decoding with output size exactly what's necessary => must work */
524  FUZ_DISPLAYTEST();
525  decodedBuffer[blockSize] = 0;
526  { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize);
527  FUZ_CHECKTEST(r<0, "LZ4_decompress_safe failed despite sufficient space");
528  FUZ_CHECKTEST(r!=blockSize, "LZ4_decompress_safe did not regenerate original data");
529  }
530  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
531  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
532  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
533  }
534 
535  /* Test decoding with more than enough output size => must work */
536  FUZ_DISPLAYTEST();
537  decodedBuffer[blockSize] = 0;
538  decodedBuffer[blockSize+1] = 0;
539  { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize+1);
540  FUZ_CHECKTEST(r<0, "LZ4_decompress_safe failed despite amply sufficient space");
541  FUZ_CHECKTEST(r!=blockSize, "LZ4_decompress_safe did not regenerate original data");
542  }
543  FUZ_CHECKTEST(decodedBuffer[blockSize+1], "LZ4_decompress_safe overrun specified output buffer size");
544  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
545  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");
546  }
547 
548  /* Test decoding with output size being one byte too short => must fail */
549  FUZ_DISPLAYTEST();
550  decodedBuffer[blockSize-1] = 0;
551  { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize-1);
552  FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short");
553  }
554  FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe overrun specified output buffer size");
555 
556  /* Test decoding with output size being 10 bytes too short => must fail */
557  FUZ_DISPLAYTEST();
558  if (blockSize>10) {
559  decodedBuffer[blockSize-10] = 0;
560  { int const r = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize-10);
561  FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to Output Size being 10 bytes too short");
562  }
563  FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe overrun specified output buffer size");
564  }
565 
566  /* noisy src decompression test */
567 
568  /* insert noise into src */
569  { U32 const maxNbBits = FUZ_highbit32((U32)compressedSize);
570  size_t pos = 0;
571  for (;;) {
572  /* keep some original src */
573  { U32 const nbBits = FUZ_rand(&randState) % maxNbBits;
574  size_t const mask = (1<<nbBits) - 1;
575  size_t const skipLength = FUZ_rand(&randState) & mask;
576  pos += skipLength;
577  }
578  if (pos >= (size_t)compressedSize) break;
579  /* add noise */
580  { U32 const nbBitsCodes = FUZ_rand(&randState) % maxNbBits;
581  U32 const nbBits = nbBitsCodes ? nbBitsCodes-1 : 0;
582  size_t const mask = (1<<nbBits) - 1;
583  size_t const rNoiseLength = (FUZ_rand(&randState) & mask) + 1;
584  size_t const noiseLength = MIN(rNoiseLength, (size_t)compressedSize-pos);
585  size_t const noiseStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - noiseLength);
586  memcpy(cBuffer_exact + pos, (const char*)CNBuffer + noiseStart, noiseLength);
587  pos += noiseLength;
588  } } }
589 
590  /* decompress noisy source */
591  FUZ_DISPLAYTEST("decompress noisy source ");
592  { U32 const endMark = 0xA9B1C3D6;
593  memcpy(decodedBuffer+blockSize, &endMark, sizeof(endMark));
594  { int const decompressResult = LZ4_decompress_safe(cBuffer_exact, decodedBuffer, compressedSize, blockSize);
595  /* result *may* be an unlikely success, but even then, it must strictly respect dst buffer boundaries */
596  FUZ_CHECKTEST(decompressResult > blockSize, "LZ4_decompress_safe on noisy src : result is too large : %u > %u (dst buffer)", (unsigned)decompressResult, (unsigned)blockSize);
597  }
598  { U32 endCheck; memcpy(&endCheck, decodedBuffer+blockSize, sizeof(endCheck));
599  FUZ_CHECKTEST(endMark!=endCheck, "LZ4_decompress_safe on noisy src : dst buffer overflow");
600  } } /* noisy src decompression test */
601 
602  free(cBuffer_exact);
603  }
604 
605  /* Test decoding with input size being one byte too short => must fail */
606  FUZ_DISPLAYTEST();
607  { int const r = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize-1, blockSize);
608  FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short (blockSize=%i, result=%i, compressedSize=%i)", blockSize, r, compressedSize);
609  }
610 
611  /* Test decoding with input size being one byte too large => must fail */
612  FUZ_DISPLAYTEST();
613  decodedBuffer[blockSize] = 0;
614  { int const r = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize+1, blockSize);
615  FUZ_CHECKTEST(r>=0, "LZ4_decompress_safe should have failed, due to input size being too large");
616  }
617  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
618 
619  /* Test partial decoding => must work */
620  FUZ_DISPLAYTEST("test LZ4_decompress_safe_partial");
621  { size_t const missingOutBytes = FUZ_rand(&randState) % (unsigned)blockSize;
622  int const targetSize = (int)((size_t)blockSize - missingOutBytes);
623  size_t const extraneousInBytes = FUZ_rand(&randState) % 2;
624  int const inCSize = (int)((size_t)compressedSize + extraneousInBytes);
625  char const sentinel = decodedBuffer[targetSize] = block[targetSize] ^ 0x5A;
626  int const decResult = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, inCSize, targetSize, blockSize);
627  FUZ_CHECKTEST(decResult<0, "LZ4_decompress_safe_partial failed despite valid input data (error:%i)", decResult);
628  FUZ_CHECKTEST(decResult != targetSize, "LZ4_decompress_safe_partial did not regenerated required amount of data (%i < %i <= %i)", decResult, targetSize, blockSize);
629  FUZ_CHECKTEST(decodedBuffer[targetSize] != sentinel, "LZ4_decompress_safe_partial overwrite beyond requested size (though %i <= %i <= %i)", decResult, targetSize, blockSize);
630  FUZ_CHECKTEST(memcmp(block, decodedBuffer, (size_t)targetSize), "LZ4_decompress_safe_partial: corruption detected in regenerated data");
631  }
632 
633  /* Test Compression with limited output size */
634 
635  /* Test compression with output size being exactly what's necessary (should work) */
636  FUZ_DISPLAYTEST("test LZ4_compress_default() with output buffer just the right size");
637  ret = LZ4_compress_default(block, compressedBuffer, blockSize, compressedSize);
638  FUZ_CHECKTEST(ret==0, "LZ4_compress_default() failed despite sufficient space");
639 
640  /* Test compression with output size being exactly what's necessary and external state (should work) */
641  FUZ_DISPLAYTEST("test LZ4_compress_fast_extState() with output buffer just the right size");
642  ret = LZ4_compress_fast_extState(stateLZ4, block, compressedBuffer, blockSize, compressedSize, 1);
643  FUZ_CHECKTEST(ret==0, "LZ4_compress_fast_extState() failed despite sufficient space");
644 
645  /* Test HC compression with output size being exactly what's necessary (should work) */
646  FUZ_DISPLAYTEST("test LZ4_compress_HC() with output buffer just the right size");
647  ret = LZ4_compress_HC(block, compressedBuffer, blockSize, HCcompressedSize, compressionLevel);
648  FUZ_CHECKTEST(ret==0, "LZ4_compress_HC() failed despite sufficient space");
649 
650  /* Test HC compression with output size being exactly what's necessary (should work) */
651  FUZ_DISPLAYTEST("test LZ4_compress_HC_extStateHC() with output buffer just the right size");
652  ret = LZ4_compress_HC_extStateHC(stateLZ4HC, block, compressedBuffer, blockSize, HCcompressedSize, compressionLevel);
653  FUZ_CHECKTEST(ret==0, "LZ4_compress_HC_extStateHC() failed despite sufficient space");
654 
655  /* Test compression with missing bytes into output buffer => must fail */
656  FUZ_DISPLAYTEST("test LZ4_compress_default() with output buffer a bit too short");
657  { int missingBytes = (FUZ_rand(&randState) % 0x3F) + 1;
658  if (missingBytes >= compressedSize) missingBytes = compressedSize-1;
659  missingBytes += !missingBytes; /* avoid special case missingBytes==0 */
660  compressedBuffer[compressedSize-missingBytes] = 0;
661  { int const cSize = LZ4_compress_default(block, compressedBuffer, blockSize, compressedSize-missingBytes);
662  FUZ_CHECKTEST(cSize, "LZ4_compress_default should have failed (output buffer too small by %i byte)", missingBytes);
663  }
664  FUZ_CHECKTEST(compressedBuffer[compressedSize-missingBytes], "LZ4_compress_default overran output buffer ! (%i missingBytes)", missingBytes)
665  }
666 
667  /* Test HC compression with missing bytes into output buffer => must fail */
668  FUZ_DISPLAYTEST("test LZ4_compress_HC() with output buffer a bit too short");
669  { int missingBytes = (FUZ_rand(&randState) % 0x3F) + 1;
670  if (missingBytes >= HCcompressedSize) missingBytes = HCcompressedSize-1;
671  missingBytes += !missingBytes; /* avoid special case missingBytes==0 */
672  compressedBuffer[HCcompressedSize-missingBytes] = 0;
673  { int const hcSize = LZ4_compress_HC(block, compressedBuffer, blockSize, HCcompressedSize-missingBytes, compressionLevel);
674  FUZ_CHECKTEST(hcSize, "LZ4_compress_HC should have failed (output buffer too small by %i byte)", missingBytes);
675  }
676  FUZ_CHECKTEST(compressedBuffer[HCcompressedSize-missingBytes], "LZ4_compress_HC overran output buffer ! (%i missingBytes)", missingBytes)
677  }
678 
679 
680  /*-******************/
681  /* Dictionary tests */
682  /*-******************/
683 
684  /* Compress using dictionary */
685  FUZ_DISPLAYTEST("test LZ4_compress_fast_continue() with dictionary of size %i", dictSize);
688  LZ4_compress_fast_continue (&LZ4_stream, dict, compressedBuffer, dictSize, (int)compressedBufferSize, 1); /* Just to fill hash tables */
689  blockContinueCompressedSize = LZ4_compress_fast_continue (&LZ4_stream, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
690  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_fast_continue failed");
691  }
692 
693  /* Decompress with dictionary as prefix */
694  FUZ_DISPLAYTEST("test LZ4_decompress_fast_usingDict() with dictionary as prefix");
695  memcpy(decodedBuffer, dict, dictSize);
696  ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer+dictSize, blockSize, decodedBuffer, dictSize);
697  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
698  { U32 const crcCheck = XXH32(decodedBuffer+dictSize, (size_t)blockSize, 0);
699  if (crcCheck!=crcOrig) {
700  FUZ_findDiff(block, decodedBuffer);
701  EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
702  } }
703 
704  FUZ_DISPLAYTEST("test LZ4_decompress_safe_usingDict()");
705  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer+dictSize, blockContinueCompressedSize, blockSize, decodedBuffer, dictSize);
706  FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
707  { U32 const crcCheck = XXH32(decodedBuffer+dictSize, (size_t)blockSize, 0);
708  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
709  }
710 
711  /* Compress using External dictionary */
712  FUZ_DISPLAYTEST("test LZ4_compress_fast_continue(), with non-contiguous dictionary");
713  dict -= (size_t)(FUZ_rand(&randState) & 0xF) + 1; /* create space, so now dictionary is an ExtDict */
714  if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
715  LZ4_loadDict(&LZ4dictBody, dict, dictSize);
716  blockContinueCompressedSize = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
717  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_fast_continue failed");
718 
719  FUZ_DISPLAYTEST("LZ4_compress_fast_continue() with dictionary and output buffer too short by one byte");
720  LZ4_loadDict(&LZ4dictBody, dict, dictSize);
721  ret = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, blockContinueCompressedSize-1, 1);
722  FUZ_CHECKTEST(ret>0, "LZ4_compress_fast_continue using ExtDict should fail : one missing byte for output buffer : %i written, %i buffer", ret, blockContinueCompressedSize);
723 
724  FUZ_DISPLAYTEST("test LZ4_compress_fast_continue() with dictionary loaded with LZ4_loadDict()");
725  DISPLAYLEVEL(5, " compress %i bytes from buffer(%p) into dst(%p) using dict(%p) of size %i \n",
726  blockSize, (const void *)block, (void *)decodedBuffer, (const void *)dict, dictSize);
727  LZ4_loadDict(&LZ4dictBody, dict, dictSize);
728  ret = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
729  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
730  FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue should work : enough size available within output buffer");
731 
732  /* Decompress with dictionary as external */
733  FUZ_DISPLAYTEST("test LZ4_decompress_fast_usingDict() with dictionary as extDict");
734  DISPLAYLEVEL(5, " decoding %i bytes from buffer(%p) using dict(%p) of size %i \n",
735  blockSize, (void *)decodedBuffer, (const void *)dict, dictSize);
736  decodedBuffer[blockSize] = 0;
737  ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize, dict, dictSize);
738  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
739  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
740  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
741  if (crcCheck!=crcOrig) {
742  FUZ_findDiff(block, decodedBuffer);
743  EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
744  } }
745 
746  FUZ_DISPLAYTEST();
747  decodedBuffer[blockSize] = 0;
748  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
749  FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
750  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
751  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
752  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
753  }
754 
755  FUZ_DISPLAYTEST();
756  decodedBuffer[blockSize-1] = 0;
757  ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize-1, dict, dictSize);
758  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast_usingDict should have failed : wrong original size (-1 byte)");
759  FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
760 
761  FUZ_DISPLAYTEST();
762  decodedBuffer[blockSize-1] = 0;
763  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-1, dict, dictSize);
764  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : not enough output size (-1 byte)");
765  FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
766 
767  FUZ_DISPLAYTEST();
768  { int const missingBytes = (FUZ_rand(&randState) & 0xF) + 2;
769  if (blockSize > missingBytes) {
770  decodedBuffer[blockSize-missingBytes] = 0;
771  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-missingBytes, dict, dictSize);
772  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : output buffer too small (-%i byte)", missingBytes);
773  FUZ_CHECKTEST(decodedBuffer[blockSize-missingBytes], "LZ4_decompress_safe_usingDict overrun specified output buffer size (-%i byte) (blockSize=%i)", missingBytes, blockSize);
774  } }
775 
776  /* Compress using external dictionary stream */
778  int expectedSize;
779  U32 expectedCrc;
780 
781  FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_loadDict()");
782  LZ4_loadDict(&LZ4dictBody, dict, dictSize);
783  expectedSize = LZ4_compress_fast_continue(&LZ4dictBody, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
784  FUZ_CHECKTEST(expectedSize<=0, "LZ4_compress_fast_continue reference compression for extDictCtx should have succeeded");
785  expectedCrc = XXH32(compressedBuffer, (size_t)expectedSize, 0);
786 
787  FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_attach_dictionary()");
788  LZ4_loadDict(&LZ4dictBody, dict, dictSize);
790  LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
791  blockContinueCompressedSize = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, (int)compressedBufferSize, 1);
792  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_fast_continue using extDictCtx failed");
793 
794  /* In the future, it might be desirable to let extDictCtx mode's
795  * output diverge from the output generated by regular extDict mode.
796  * Until that time, this comparison serves as a good regression
797  * test.
798  */
799  FUZ_CHECKTEST(blockContinueCompressedSize != expectedSize, "LZ4_compress_fast_continue using extDictCtx produced different-sized output (%d expected vs %d actual)", expectedSize, blockContinueCompressedSize);
800  FUZ_CHECKTEST(XXH32(compressedBuffer, (size_t)blockContinueCompressedSize, 0) != expectedCrc, "LZ4_compress_fast_continue using extDictCtx produced different output");
801 
802  FUZ_DISPLAYTEST("LZ4_compress_fast_continue() after LZ4_attach_dictionary(), but output buffer is 1 byte too short");
804  LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
805  ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize-1, 1);
806  FUZ_CHECKTEST(ret>0, "LZ4_compress_fast_continue using extDictCtx should fail : one missing byte for output buffer : %i written, %i buffer", ret, blockContinueCompressedSize);
807  /* note : context is no longer dirty after a failed compressed block */
808 
809  FUZ_DISPLAYTEST();
811  LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
812  ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
813  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
814  FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue using extDictCtx should work : enough size available within output buffer");
815  FUZ_CHECKTEST(ret != expectedSize, "LZ4_compress_fast_continue using extDictCtx produced different-sized output");
816  FUZ_CHECKTEST(XXH32(compressedBuffer, (size_t)ret, 0) != expectedCrc, "LZ4_compress_fast_continue using extDictCtx produced different output");
817 
818  FUZ_DISPLAYTEST();
820  LZ4_attach_dictionary(&LZ4_stream, &LZ4dictBody);
821  ret = LZ4_compress_fast_continue(&LZ4_stream, block, compressedBuffer, blockSize, blockContinueCompressedSize, 1);
822  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
823  FUZ_CHECKTEST(ret<=0, "LZ4_compress_fast_continue using extDictCtx with re-used context should work : enough size available within output buffer");
824  FUZ_CHECKTEST(ret != expectedSize, "LZ4_compress_fast_continue using extDictCtx produced different-sized output");
825  FUZ_CHECKTEST(XXH32(compressedBuffer, (size_t)ret, 0) != expectedCrc, "LZ4_compress_fast_continue using extDictCtx produced different output");
826  }
827 
828  /* Decompress with dictionary as external */
829  FUZ_DISPLAYTEST();
830  decodedBuffer[blockSize] = 0;
831  ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize, dict, dictSize);
832  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
833  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
834  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
835  if (crcCheck!=crcOrig) {
836  FUZ_findDiff(block, decodedBuffer);
837  EXIT_MSG("LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);
838  } }
839 
840  FUZ_DISPLAYTEST();
841  decodedBuffer[blockSize] = 0;
842  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
843  FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
844  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
845  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
846  FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");
847  }
848 
849  FUZ_DISPLAYTEST();
850  decodedBuffer[blockSize-1] = 0;
851  ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize-1, dict, dictSize);
852  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast_usingDict should have failed : wrong original size (-1 byte)");
853  FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast_usingDict overrun specified output buffer size");
854 
855  FUZ_DISPLAYTEST();
856  decodedBuffer[blockSize-1] = 0;
857  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-1, dict, dictSize);
858  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : not enough output size (-1 byte)");
859  FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
860 
861  FUZ_DISPLAYTEST("LZ4_decompress_safe_usingDict with a too small output buffer");
862  { int const missingBytes = (FUZ_rand(&randState) & 0xF) + 2;
863  if (blockSize > missingBytes) {
864  decodedBuffer[blockSize-missingBytes] = 0;
865  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-missingBytes, dict, dictSize);
866  FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : output buffer too small (-%i byte)", missingBytes);
867  FUZ_CHECKTEST(decodedBuffer[blockSize-missingBytes], "LZ4_decompress_safe_usingDict overrun specified output buffer size (-%i byte) (blockSize=%i)", missingBytes, blockSize);
868  } }
869 
870  /* Compress HC using External dictionary */
871  FUZ_DISPLAYTEST("LZ4_compress_HC_continue with an external dictionary");
872  dict -= (FUZ_rand(&randState) & 7); /* even bigger separation */
873  if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
874  LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
876  blockContinueCompressedSize = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
877  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue failed");
878  FUZ_CHECKTEST(LZ4dictHC->internal_donotuse.dirty, "Context should be clean");
879 
880  FUZ_DISPLAYTEST("LZ4_compress_HC_continue with same external dictionary, but output buffer 1 byte too short");
881  LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
882  ret = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
883  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);
884  /* note : context is no longer dirty after a failed compressed block */
885 
886  FUZ_DISPLAYTEST("LZ4_compress_HC_continue with same external dictionary, and output buffer exactly the right size");
887  LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
888  ret = LZ4_compress_HC_continue(LZ4dictHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
889  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue size is different : ret(%i) != expected(%i)", ret, blockContinueCompressedSize);
890  FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue should work : enough size available within output buffer");
891  FUZ_CHECKTEST(LZ4dictHC->internal_donotuse.dirty, "Context should be clean");
892 
893  FUZ_DISPLAYTEST();
894  decodedBuffer[blockSize] = 0;
895  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
896  FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
897  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
898  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
899  if (crcCheck!=crcOrig) {
900  FUZ_findDiff(block, decodedBuffer);
901  EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
902  } }
903 
904  /* Compress HC using external dictionary stream */
905  FUZ_DISPLAYTEST();
907 
908  LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
911  blockContinueCompressedSize = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, (int)compressedBufferSize);
912  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue with ExtDictCtx failed");
913  FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
914 
915  FUZ_DISPLAYTEST();
918  ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
919  FUZ_CHECKTEST(ret>0, "LZ4_compress_HC_continue using ExtDictCtx should fail : one missing byte for output buffer (%i != %i)", ret, blockContinueCompressedSize);
920  /* note : context is no longer dirty after a failed compressed block */
921 
922  FUZ_DISPLAYTEST();
925  ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
926  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue using ExtDictCtx size is different (%i != %i)", ret, blockContinueCompressedSize);
927  FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue using ExtDictCtx should work : enough size available within output buffer");
928  FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
929 
930  FUZ_DISPLAYTEST();
933  ret = LZ4_compress_HC_continue(LZ4_streamHC, block, compressedBuffer, blockSize, blockContinueCompressedSize);
934  FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_HC_continue using ExtDictCtx and fast reset size is different (%i != %i)",
935  ret, blockContinueCompressedSize);
936  FUZ_CHECKTEST(ret<=0, "LZ4_compress_HC_continue using ExtDictCtx and fast reset should work : enough size available within output buffer");
937  FUZ_CHECKTEST(LZ4_streamHC->internal_donotuse.dirty, "Context should be clean");
938 
940  }
941 
942  FUZ_DISPLAYTEST();
943  decodedBuffer[blockSize] = 0;
944  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
945  FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
946  FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size");
947  { U32 const crcCheck = XXH32(decodedBuffer, (size_t)blockSize, 0);
948  if (crcCheck!=crcOrig) {
949  FUZ_findDiff(block, decodedBuffer);
950  EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
951  } }
952 
953  /* Compress HC continue destSize */
954  FUZ_DISPLAYTEST();
955  { int const availableSpace = (int)(FUZ_rand(&randState) % (U32)blockSize) + 5;
956  int consumedSize = blockSize;
957  FUZ_DISPLAYTEST();
958  LZ4_loadDictHC(LZ4dictHC, dict, dictSize);
960  blockContinueCompressedSize = LZ4_compress_HC_continue_destSize(LZ4dictHC, block, compressedBuffer, &consumedSize, availableSpace);
961  DISPLAYLEVEL(5, " LZ4_compress_HC_continue_destSize : compressed %6i/%6i into %6i/%6i at cLevel=%i \n",
962  consumedSize, blockSize, blockContinueCompressedSize, availableSpace, compressionLevel);
963  FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_HC_continue_destSize failed");
964  FUZ_CHECKTEST(blockContinueCompressedSize > availableSpace, "LZ4_compress_HC_continue_destSize write overflow");
965  FUZ_CHECKTEST(consumedSize > blockSize, "LZ4_compress_HC_continue_destSize read overflow");
966 
967  FUZ_DISPLAYTEST();
968  decodedBuffer[consumedSize] = 0;
969  ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, consumedSize, dict, dictSize);
970  FUZ_CHECKTEST(ret != consumedSize, "LZ4_decompress_safe_usingDict regenerated %i bytes (%i expected)", ret, consumedSize);
971  FUZ_CHECKTEST(decodedBuffer[consumedSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size")
972  { U32 const crcSrc = XXH32(block, (size_t)consumedSize, 0);
973  U32 const crcDst = XXH32(decodedBuffer, (size_t)consumedSize, 0);
974  if (crcSrc!=crcDst) {
975  FUZ_findDiff(block, decodedBuffer);
976  EXIT_MSG("LZ4_decompress_safe_usingDict corrupted decoded data");
977  } }
978  }
979 
980  /* ***** End of tests *** */
981  /* Fill stats */
982  assert(blockSize >= 0);
983  bytes += (unsigned)blockSize;
984  assert(compressedSize >= 0);
985  cbytes += (unsigned)compressedSize;
986  assert(HCcompressedSize >= 0);
987  hcbytes += (unsigned)HCcompressedSize;
988  assert(blockContinueCompressedSize >= 0);
989  ccbytes += (unsigned)blockContinueCompressedSize;
990  }
991 
992  if (nbCycles<=1) nbCycles = cycleNb; /* end by time */
993  bytes += !bytes; /* avoid division by 0 */
994  printf("\r%7u /%7u - ", cycleNb, nbCycles);
995  printf("all tests completed successfully \n");
996  printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100);
997  printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100);
998  printf("ratio with dict: %0.3f%%\n", (double)ccbytes/bytes*100);
999 
1000  /* release memory */
1001  free(CNBuffer);
1002  free(compressedBuffer);
1003  free(decodedBuffer);
1004  FUZ_freeLowAddr(lowAddrBuffer, labSize);
1005  LZ4_freeStreamHC(LZ4dictHC);
1006  free(stateLZ4);
1007  free(stateLZ4HC);
1008  return result;
1009 }
#define mask()
static ut8 bytes[32]
Definition: asm_arc.c:23
LZ4_streamHC_t LZ4_streamHC
Definition: fullbench.c:253
static LZ4_stream_t LZ4_stream
Definition: fullbench.c:169
#define FUZ_MAX_DICT_SIZE
Definition: fuzzer.c:80
#define FUZ_CHECKTEST(cond,...)
#define KB
Definition: fuzzer.c:86
#define COMPRESSIBLE_NOISE_LENGTH
Definition: fuzzer.c:78
#define FUZ_DISPLAYTEST(...)
#define EXIT_MSG(...)
static void FUZ_fillCompressibleNoiseBuffer(void *buffer, size_t bufferSize, double proba, U32 *seed)
Definition: fuzzer.c:146
#define DISPLAYLEVEL(l,...)
Definition: fuzzer.c:95
#define PRIME3
Definition: fuzzer.c:84
static void FUZ_freeLowAddr(void *buffer, size_t size)
Definition: fuzzer.c:291
#define FUZ_MAX_BLOCK_SIZE
Definition: fuzzer.c:79
static U32 FUZ_highbit32(U32 v32)
Definition: fuzzer.c:125
static void FUZ_findDiff(const void *buff1, const void *buff2)
Definition: fuzzer.c:306
static void * FUZ_createLowAddr(size_t size)
Definition: fuzzer.c:286
static void FUZ_displayUpdate(unsigned testNb)
Definition: fuzzer.c:109
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static void struct sockaddr socklen_t static fromlen static backlog static fork char char char static envp int struct rusage static rusage struct utsname static buf struct sembuf unsigned
Definition: sflib.h:97
XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed)
Definition: xxhash.c:392
int LZ4_compress_fast_extState(void *state, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
Definition: lz4.c:1284
int LZ4_decompress_fast_usingDict(const char *source, char *dest, int originalSize, const char *dictStart, int dictSize)
Definition: lz4.c:2419
int LZ4_compressBound(int isize)
Definition: lz4.c:674
int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize)
Definition: lz4.c:1475
int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxOutputSize, const char *dictStart, int dictSize)
Definition: lz4.c:2404
LZ4_stream_t * LZ4_initStream(void *buffer, size_t size)
Definition: lz4.c:1443
int LZ4_compress_default(const char *src, char *dst, int srcSize, int maxOutputSize)
Definition: lz4.c:1373
int LZ4_compress_destSize(const char *src, char *dst, int *srcSizePtr, int targetDstSize)
Definition: lz4.c:1399
int LZ4_sizeofState(void)
Definition: lz4.c:675
void LZ4_resetStream_fast(LZ4_stream_t *ctx)
Definition: lz4.c:1461
LZ4_FORCE_O2 int LZ4_decompress_fast(const char *source, char *dest, int originalSize)
Definition: lz4.c:2188
LZ4_FORCE_O2 int LZ4_decompress_safe_partial(const char *src, char *dst, int compressedSize, int targetOutputSize, int dstCapacity)
Definition: lz4.c:2179
int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
Definition: lz4.c:1565
int LZ4_compress_fast_extState_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration)
Definition: lz4.c:1316
void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream)
Definition: lz4.c:1517
char int srcSize
Definition: lz4.h:697
char int compressedSize
Definition: lz4.h:724
int LZ4_compress_HC_extStateHC(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:947
void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
Definition: lz4hc.c:1077
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1027
int LZ4_freeHC(void *LZ4HC_Data)
Definition: lz4hc.c:1222
int LZ4_sizeofStateHC(void)
Definition: lz4hc.c:921
int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int targetDestSize)
Definition: lz4hc.c:1146
void * LZ4_createHC(const char *inputBuffer)
Definition: lz4hc.c:1214
int LZ4_compress_HC_destSize(void *state, const char *source, char *dest, int *sourceSizePtr, int targetDestSize, int cLevel)
Definition: lz4hc.c:970
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
Definition: lz4hc.c:994
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:1138
int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:954
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:985
int LZ4_compress_HC_extStateHC_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:935
void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1041
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:1056
#define LZ4HC_CLEVEL_MAX
Definition: lz4hc.h:50
char int int compressionLevel
Definition: lz4hc.h:258
assert(limit<=UINT32_MAX/2)
LZ4HC_CCtx_internal internal_donotuse
Definition: lz4hc.h:227

References assert(), bytes, compressedSize, COMPRESSIBLE_NOISE_LENGTH, compressionLevel, LZ4HC_CCtx_internal::dirty, DISPLAY, DISPLAYLEVEL, test-lz4-list::exit, EXIT_MSG, free(), FUZ_CHECKTEST, FUZ_createLowAddr(), FUZ_DISPLAYTEST, FUZ_displayUpdate(), FUZ_fillCompressibleNoiseBuffer(), FUZ_findDiff(), FUZ_freeLowAddr(), FUZ_GetClockSpan(), FUZ_highbit32(), FUZ_MAX_BLOCK_SIZE, FUZ_MAX_DICT_SIZE, FUZ_rand(), int, LZ4_streamHC_u::internal_donotuse, KB, LZ4_attach_dictionary(), LZ4_attach_HC_dictionary(), LZ4_compress_default(), LZ4_compress_destSize(), LZ4_compress_fast_continue(), LZ4_compress_fast_extState(), LZ4_compress_fast_extState_fastReset(), LZ4_compress_HC(), LZ4_compress_HC_continue(), LZ4_compress_HC_continue_destSize(), LZ4_compress_HC_destSize(), LZ4_compress_HC_extStateHC(), LZ4_compress_HC_extStateHC_fastReset(), LZ4_compressBound(), LZ4_createHC(), LZ4_createStreamHC(), LZ4_decompress_fast(), LZ4_decompress_fast_usingDict(), LZ4_decompress_safe(), LZ4_decompress_safe_partial(), LZ4_decompress_safe_usingDict(), LZ4_freeHC(), LZ4_freeStreamHC(), LZ4_initStream(), LZ4_loadDict(), LZ4_loadDictHC(), LZ4_resetStream_fast(), LZ4_resetStreamHC_fast(), LZ4_setCompressionLevel(), LZ4_sizeofState(), LZ4_sizeofStateHC(), LZ4_stream, LZ4_streamHC, LZ4HC_CLEVEL_MAX, malloc(), mask, memcpy(), MIN, NULL, pos, PRIME3, printf(), r, srcSize, U32, unsigned, and XXH32().

Referenced by main().

◆ FUZ_unitTests()

static void FUZ_unitTests ( int  compressionLevel)
static

Definition at line 1016 of file fuzzer.c.

1017 {
1018  const unsigned testNb = 0;
1019  const unsigned seed = 0;
1020  const unsigned cycleNb= 0;
1021  char* testInput = (char*)malloc(testInputSize);
1022  char* testCompressed = (char*)malloc(testCompressedSize);
1023  char* testVerify = (char*)malloc(testInputSize);
1024  char ringBuffer[ringBufferSize] = {0};
1025  U32 randState = 1;
1026 
1027  /* Init */
1028  if (!testInput || !testCompressed || !testVerify) {
1029  EXIT_MSG("not enough memory for FUZ_unitTests");
1030  }
1031  FUZ_fillCompressibleNoiseBuffer(testInput, testInputSize, 0.50, &randState);
1032 
1033  /* 32-bits address space overflow test */
1035 
1036  /* Test decoding with empty input */
1037  DISPLAYLEVEL(3, "LZ4_decompress_safe() with empty input \n");
1038  LZ4_decompress_safe(testCompressed, testVerify, 0, testInputSize);
1039 
1040  /* Test decoding with a one byte input */
1041  DISPLAYLEVEL(3, "LZ4_decompress_safe() with one byte input \n");
1042  { char const tmp = (char)0xFF;
1043  LZ4_decompress_safe(&tmp, testVerify, 1, testInputSize);
1044  }
1045 
1046  /* Test decoding shortcut edge case */
1047  DISPLAYLEVEL(3, "LZ4_decompress_safe() with shortcut edge case \n");
1048  { char tmp[17];
1049  /* 14 bytes of literals, followed by a 14 byte match.
1050  * Should not read beyond the end of the buffer.
1051  * See https://github.com/lz4/lz4/issues/508. */
1052  *tmp = (char)0xEE;
1053  memset(tmp + 1, 0, 14);
1054  tmp[15] = 14;
1055  tmp[16] = 0;
1056  { int const r = LZ4_decompress_safe(tmp, testVerify, sizeof(tmp), testInputSize);
1057  FUZ_CHECKTEST(r >= 0, "LZ4_decompress_safe() should fail");
1058  } }
1059 
1060 
1061  /* to be tested with undefined sanitizer */
1062  DISPLAYLEVEL(3, "LZ4_compress_default() with NULL input:");
1063  { int const maxCSize = LZ4_compressBound(0);
1064  int const cSize = LZ4_compress_default(NULL, testCompressed, 0, maxCSize);
1065  FUZ_CHECKTEST(!(cSize==1 && testCompressed[0]==0),
1066  "compressing empty should give byte 0"
1067  " (maxCSize == %i) (cSize == %i) (byte == 0x%02X)",
1068  maxCSize, cSize, testCompressed[0]);
1069  }
1070  DISPLAYLEVEL(3, " OK \n");
1071 
1072  DISPLAYLEVEL(3, "LZ4_compress_default() with both NULL input and output:");
1073  { int const cSize = LZ4_compress_default(NULL, NULL, 0, 0);
1074  FUZ_CHECKTEST(cSize != 0,
1075  "compressing into NULL must fail"
1076  " (cSize == %i != 0)", cSize);
1077  }
1078  DISPLAYLEVEL(3, " OK \n");
1079 
1080  /* in-place compression test */
1081  DISPLAYLEVEL(3, "in-place compression using LZ4_compress_default() :");
1082  { int const sampleSize = 65 KB;
1083  int const maxCSize = LZ4_COMPRESSBOUND(sampleSize);
1084  int const outSize = LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCSize);
1085  int const startInputIndex = outSize - sampleSize;
1086  char* const startInput = testCompressed + startInputIndex;
1087  XXH32_hash_t const crcOrig = XXH32(testInput, sampleSize, 0);
1088  int cSize;
1089  assert(outSize < (int)testCompressedSize);
1090  memcpy(startInput, testInput, sampleSize); /* copy at end of buffer */
1091  /* compress in-place */
1092  cSize = LZ4_compress_default(startInput, testCompressed, sampleSize, maxCSize);
1093  assert(cSize != 0); /* ensure compression is successful */
1094  assert(maxCSize < INT_MAX);
1095  assert(cSize <= maxCSize);
1096  /* decompress and verify */
1097  { int const dSize = LZ4_decompress_safe(testCompressed, testVerify, cSize, testInputSize);
1098  assert(dSize == sampleSize); /* correct size */
1099  { XXH32_hash_t const crcCheck = XXH32(testVerify, (size_t)dSize, 0);
1100  FUZ_CHECKTEST(crcCheck != crcOrig, "LZ4_decompress_safe decompression corruption");
1101  } } }
1102  DISPLAYLEVEL(3, " OK \n");
1103 
1104  /* in-place decompression test */
1105  DISPLAYLEVEL(3, "in-place decompression, limit case:");
1106  { int const sampleSize = 65 KB;
1107 
1108  FUZ_fillCompressibleNoiseBuffer(testInput, sampleSize, 0.0, &randState);
1109  memset(testInput, 0, 267); /* calculated exactly so that compressedSize == originalSize-1 */
1110 
1111  { XXH64_hash_t const crcOrig = XXH64(testInput, sampleSize, 0);
1112  int const cSize = LZ4_compress_default(testInput, testCompressed, sampleSize, testCompressedSize);
1113  assert(cSize == sampleSize - 1); /* worst case for in-place decompression */
1114 
1115  { int const bufferSize = LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(sampleSize);
1116  int const startInputIndex = bufferSize - cSize;
1117  char* const startInput = testVerify + startInputIndex;
1118  memcpy(startInput, testCompressed, cSize);
1119 
1120  /* decompress and verify */
1121  { int const dSize = LZ4_decompress_safe(startInput, testVerify, cSize, sampleSize);
1122  assert(dSize == sampleSize); /* correct size */
1123  { XXH64_hash_t const crcCheck = XXH64(testVerify, (size_t)dSize, 0);
1124  FUZ_CHECKTEST(crcCheck != crcOrig, "LZ4_decompress_safe decompression corruption");
1125  } } } } }
1126  DISPLAYLEVEL(3, " OK \n");
1127 
1128  DISPLAYLEVEL(3, "LZ4_initStream with multiple valid alignments : ");
1129  { typedef struct {
1130  LZ4_stream_t state1;
1131  LZ4_stream_t state2;
1132  char c;
1133  LZ4_stream_t state3;
1134  } shct;
1135  shct* const shc = (shct*)malloc(sizeof(*shc));
1136  assert(shc != NULL);
1137  memset(shc, 0, sizeof(*shc));
1138  DISPLAYLEVEL(4, "state1(%p) state2(%p) state3(%p) LZ4_stream_t size(0x%x): ",
1139  &(shc->state1), &(shc->state2), &(shc->state3), (unsigned)sizeof(LZ4_stream_t));
1140  FUZ_CHECKTEST( LZ4_initStream(&(shc->state1), sizeof(shc->state1)) == NULL, "state1 (%p) failed init", &(shc->state1) );
1141  FUZ_CHECKTEST( LZ4_initStream(&(shc->state2), sizeof(shc->state2)) == NULL, "state2 (%p) failed init", &(shc->state2) );
1142  FUZ_CHECKTEST( LZ4_initStream(&(shc->state3), sizeof(shc->state3)) == NULL, "state3 (%p) failed init", &(shc->state3) );
1143  FUZ_CHECKTEST( LZ4_initStream((char*)&(shc->state1) + 1, sizeof(shc->state1)) != NULL,
1144  "hc1+1 (%p) init must fail, due to bad alignment", (char*)&(shc->state1) + 1 );
1145  free(shc);
1146  }
1147  DISPLAYLEVEL(3, "all inits OK \n");
1148 
1149  /* Allocation test */
1150  { LZ4_stream_t* const statePtr = LZ4_createStream();
1151  FUZ_CHECKTEST(statePtr==NULL, "LZ4_createStream() allocation failed");
1152  LZ4_freeStream(statePtr);
1153  }
1154 
1155  /* LZ4 streaming tests */
1156  { LZ4_stream_t streamingState;
1157 
1158  /* simple compression test */
1159  LZ4_initStream(&streamingState, sizeof(streamingState));
1160  { int const cs = LZ4_compress_fast_continue(&streamingState, testInput, testCompressed, testCompressedSize, testCompressedSize-1, 1);
1161  FUZ_CHECKTEST(cs==0, "LZ4_compress_fast_continue() compression failed!");
1162  { int const r = LZ4_decompress_safe(testCompressed, testVerify, cs, testCompressedSize);
1163  FUZ_CHECKTEST(r!=(int)testCompressedSize, "LZ4_decompress_safe() decompression failed");
1164  } }
1165  { U64 const crcOrig = XXH64(testInput, testCompressedSize, 0);
1166  U64 const crcNew = XXH64(testVerify, testCompressedSize, 0);
1167  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption");
1168  }
1169 
1170  /* early saveDict */
1171  DISPLAYLEVEL(3, "saveDict (right after init) : ");
1172  { LZ4_stream_t* const ctx = LZ4_initStream(&streamingState, sizeof(streamingState));
1173  assert(ctx != NULL); /* ensure init is successful */
1174 
1175  /* Check access violation with asan */
1176  FUZ_CHECKTEST( LZ4_saveDict(ctx, NULL, 0) != 0,
1177  "LZ4_saveDict() can't save anything into (NULL,0)");
1178 
1179  /* Check access violation with asan */
1180  { char tmp_buffer[240] = { 0 };
1181  FUZ_CHECKTEST( LZ4_saveDict(ctx, tmp_buffer, sizeof(tmp_buffer)) != 0,
1182  "LZ4_saveDict() can't save anything since compression hasn't started");
1183  } }
1184  DISPLAYLEVEL(3, "OK \n");
1185 
1186  /* ring buffer test */
1187  { XXH64_state_t xxhOrig;
1188  XXH64_state_t xxhNewSafe, xxhNewFast;
1189  LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
1190  const U32 maxMessageSizeLog = 10;
1191  const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
1192  U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
1193  U32 iNext = 0;
1194  U32 rNext = 0;
1195  U32 dNext = 0;
1196  const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
1197 
1198  XXH64_reset(&xxhOrig, 0);
1199  XXH64_reset(&xxhNewSafe, 0);
1200  XXH64_reset(&xxhNewFast, 0);
1201  LZ4_resetStream_fast(&streamingState);
1202  LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
1203  LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
1204 
1205  while (iNext + messageSize < testCompressedSize) {
1206  int compressedSize; U64 crcOrig;
1207  XXH64_update(&xxhOrig, testInput + iNext, messageSize);
1208  crcOrig = XXH64_digest(&xxhOrig);
1209 
1210  memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
1211  compressedSize = LZ4_compress_fast_continue(&streamingState, ringBuffer + rNext, testCompressed, (int)messageSize, testCompressedSize-ringBufferSize, 1);
1212  FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_fast_continue() compression failed");
1213 
1214  { int const r = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, (int)messageSize);
1215  FUZ_CHECKTEST(r!=(int)messageSize, "ringBuffer : LZ4_decompress_safe_continue() test failed"); }
1216 
1217  XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
1218  { U64 const crcNew = XXH64_digest(&xxhNewSafe);
1219  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
1220 
1221  { int const r = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, (int)messageSize);
1222  FUZ_CHECKTEST(r!=compressedSize, "ringBuffer : LZ4_decompress_fast_continue() test failed"); }
1223 
1224  XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
1225  { U64 const crcNew = XXH64_digest(&xxhNewFast);
1226  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
1227 
1228  /* prepare next message */
1229  iNext += messageSize;
1230  rNext += messageSize;
1231  dNext += messageSize;
1232  messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
1233  if (rNext + messageSize > ringBufferSize) rNext = 0;
1234  if (dNext + messageSize > dBufferSize) dNext = 0;
1235  } }
1236  }
1237 
1238  DISPLAYLEVEL(3, "LZ4_initStreamHC with multiple valid alignments : ");
1239  { typedef struct {
1240  LZ4_streamHC_t hc1;
1241  LZ4_streamHC_t hc2;
1242  char c;
1243  LZ4_streamHC_t hc3;
1244  } shct;
1245  shct* const shc = (shct*)malloc(sizeof(*shc));
1246  assert(shc != NULL);
1247  memset(shc, 0, sizeof(*shc));
1248  DISPLAYLEVEL(4, "hc1(%p) hc2(%p) hc3(%p) size(0x%x): ",
1249  &(shc->hc1), &(shc->hc2), &(shc->hc3), (unsigned)sizeof(LZ4_streamHC_t));
1250  FUZ_CHECKTEST( LZ4_initStreamHC(&(shc->hc1), sizeof(shc->hc1)) == NULL, "hc1 (%p) failed init", &(shc->hc1) );
1251  FUZ_CHECKTEST( LZ4_initStreamHC(&(shc->hc2), sizeof(shc->hc2)) == NULL, "hc2 (%p) failed init", &(shc->hc2) );
1252  FUZ_CHECKTEST( LZ4_initStreamHC(&(shc->hc3), sizeof(shc->hc3)) == NULL, "hc3 (%p) failed init", &(shc->hc3) );
1253  FUZ_CHECKTEST( LZ4_initStreamHC((char*)&(shc->hc1) + 1, sizeof(shc->hc1)) != NULL,
1254  "hc1+1 (%p) init must fail, due to bad alignment", (char*)&(shc->hc1) + 1 );
1255  free(shc);
1256  }
1257  DISPLAYLEVEL(3, "all inits OK \n");
1258 
1259  /* LZ4 HC streaming tests */
1260  { LZ4_streamHC_t sHC; /* statically allocated */
1261  int result;
1262  LZ4_initStreamHC(&sHC, sizeof(sHC));
1263 
1264  /* Allocation test */
1265  DISPLAYLEVEL(3, "Basic HC allocation : ");
1266  { LZ4_streamHC_t* const sp = LZ4_createStreamHC();
1267  FUZ_CHECKTEST(sp==NULL, "LZ4_createStreamHC() allocation failed");
1269  }
1270  DISPLAYLEVEL(3, "OK \n");
1271 
1272  /* simple HC compression test */
1273  DISPLAYLEVEL(3, "Simple HC round-trip : ");
1274  { U64 const crc64 = XXH64(testInput, testCompressedSize, 0);
1276  result = LZ4_compress_HC_continue(&sHC, testInput, testCompressed, testCompressedSize, testCompressedSize-1);
1277  FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
1278  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1279 
1280  result = LZ4_decompress_safe(testCompressed, testVerify, result, testCompressedSize);
1281  FUZ_CHECKTEST(result!=(int)testCompressedSize, "LZ4_decompress_safe() decompression failed");
1282  { U64 const crcNew = XXH64(testVerify, testCompressedSize, 0);
1283  FUZ_CHECKTEST(crc64!=crcNew, "LZ4_decompress_safe() decompression corruption");
1284  } }
1285  DISPLAYLEVEL(3, "OK \n");
1286 
1287  /* saveDictHC test #926 */
1288  DISPLAYLEVEL(3, "saveDictHC test #926 : ");
1289  { LZ4_streamHC_t* const ctx = LZ4_initStreamHC(&sHC, sizeof(sHC));
1290  assert(ctx != NULL); /* ensure init is successful */
1291 
1292  /* Check access violation with asan */
1293  FUZ_CHECKTEST( LZ4_saveDictHC(ctx, NULL, 0) != 0,
1294  "LZ4_saveDictHC() can't save anything into (NULL,0)");
1295 
1296  /* Check access violation with asan */
1297  { char tmp_buffer[240] = { 0 };
1298  FUZ_CHECKTEST( LZ4_saveDictHC(ctx, tmp_buffer, sizeof(tmp_buffer)) != 0,
1299  "LZ4_saveDictHC() can't save anything since compression hasn't started");
1300  } }
1301  DISPLAYLEVEL(3, "OK \n");
1302 
1303  /* long sequence test */
1304  DISPLAYLEVEL(3, "Long sequence HC_destSize test : ");
1305  { size_t const blockSize = 1 MB;
1306  size_t const targetSize = 4116; /* size carefully selected to trigger an overflow */
1307  void* const block = malloc(blockSize);
1308  void* const dstBlock = malloc(targetSize+1);
1309  BYTE const sentinel = 101;
1310  int srcSize;
1311 
1312  assert(block != NULL); assert(dstBlock != NULL);
1313  memset(block, 0, blockSize);
1314  ((char*)dstBlock)[targetSize] = sentinel;
1315 
1316  LZ4_resetStreamHC_fast(&sHC, 3);
1317  assert(blockSize < INT_MAX);
1318  srcSize = (int)blockSize;
1319  assert(targetSize < INT_MAX);
1320  result = LZ4_compress_HC_destSize(&sHC, (const char*)block, (char*)dstBlock, &srcSize, (int)targetSize, 3);
1321  DISPLAYLEVEL(4, "cSize=%i; readSize=%i; ", result, srcSize);
1322  FUZ_CHECKTEST(result != 4116, "LZ4_compress_HC_destSize() : "
1323  "compression (%i->%i) must fill dstBuffer (%i) exactly",
1324  srcSize, result, (int)targetSize);
1325  FUZ_CHECKTEST(((char*)dstBlock)[targetSize] != sentinel,
1326  "LZ4_compress_HC_destSize() overwrites dst buffer");
1327  FUZ_CHECKTEST(srcSize < 1045000, "LZ4_compress_HC_destSize() doesn't compress enough"
1328  " (%i -> %i , expected > %i)", srcSize, result, 1045000);
1329 
1330  LZ4_resetStreamHC_fast(&sHC, 3); /* make sure the context is clean after the test */
1331  free(block);
1332  free(dstBlock);
1333  }
1334  DISPLAYLEVEL(3, " OK \n");
1335 
1336  /* simple dictionary HC compression test */
1337  DISPLAYLEVEL(3, "HC dictionary compression test : ");
1338  { U64 const crc64 = XXH64(testInput + 64 KB, testCompressedSize, 0);
1340  LZ4_loadDictHC(&sHC, testInput, 64 KB);
1341  { int const cSize = LZ4_compress_HC_continue(&sHC, testInput + 64 KB, testCompressed, testCompressedSize, testCompressedSize-1);
1342  FUZ_CHECKTEST(cSize==0, "LZ4_compressHC_limitedOutput_continue() dictionary compression failed : @return = %i", cSize);
1343  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1344  { int const dSize = LZ4_decompress_safe_usingDict(testCompressed, testVerify, cSize, testCompressedSize, testInput, 64 KB);
1345  FUZ_CHECKTEST(dSize!=(int)testCompressedSize, "LZ4_decompress_safe() simple dictionary decompression test failed");
1346  } }
1347  { U64 const crcNew = XXH64(testVerify, testCompressedSize, 0);
1348  FUZ_CHECKTEST(crc64!=crcNew, "LZ4_decompress_safe() simple dictionary decompression test : corruption");
1349  } }
1350  DISPLAYLEVEL(3, " OK \n");
1351 
1352  /* multiple HC compression test with dictionary */
1353  { int result1, result2;
1354  int segSize = testCompressedSize / 2;
1355  XXH64_hash_t const crc64 = ( (void)assert((unsigned)segSize + testCompressedSize < testInputSize) ,
1356  XXH64(testInput + segSize, testCompressedSize, 0) );
1358  LZ4_loadDictHC(&sHC, testInput, segSize);
1359  result1 = LZ4_compress_HC_continue(&sHC, testInput + segSize, testCompressed, segSize, segSize -1);
1360  FUZ_CHECKTEST(result1==0, "LZ4_compressHC_limitedOutput_continue() dictionary compression failed : result = %i", result1);
1361  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1362  result2 = LZ4_compress_HC_continue(&sHC, testInput + 2*(size_t)segSize, testCompressed+result1, segSize, segSize-1);
1363  FUZ_CHECKTEST(result2==0, "LZ4_compressHC_limitedOutput_continue() dictionary compression failed : result = %i", result2);
1364  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1365 
1366  result = LZ4_decompress_safe_usingDict(testCompressed, testVerify, result1, segSize, testInput, segSize);
1367  FUZ_CHECKTEST(result!=segSize, "LZ4_decompress_safe() dictionary decompression part 1 failed");
1368  result = LZ4_decompress_safe_usingDict(testCompressed+result1, testVerify+segSize, result2, segSize, testInput, 2*segSize);
1369  FUZ_CHECKTEST(result!=segSize, "LZ4_decompress_safe() dictionary decompression part 2 failed");
1370  { XXH64_hash_t const crcNew = XXH64(testVerify, testCompressedSize, 0);
1371  FUZ_CHECKTEST(crc64!=crcNew, "LZ4_decompress_safe() dictionary decompression corruption");
1372  } }
1373 
1374  /* remote dictionary HC compression test */
1375  { U64 const crc64 = XXH64(testInput + 64 KB, testCompressedSize, 0);
1377  LZ4_loadDictHC(&sHC, testInput, 32 KB);
1378  result = LZ4_compress_HC_continue(&sHC, testInput + 64 KB, testCompressed, testCompressedSize, testCompressedSize-1);
1379  FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() remote dictionary failed : result = %i", result);
1380  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1381 
1382  result = LZ4_decompress_safe_usingDict(testCompressed, testVerify, result, testCompressedSize, testInput, 32 KB);
1383  FUZ_CHECKTEST(result!=(int)testCompressedSize, "LZ4_decompress_safe_usingDict() decompression failed following remote dictionary HC compression test");
1384  { U64 const crcNew = XXH64(testVerify, testCompressedSize, 0);
1385  FUZ_CHECKTEST(crc64!=crcNew, "LZ4_decompress_safe_usingDict() decompression corruption");
1386  } }
1387 
1388  /* multiple HC compression with ext. dictionary */
1389  { XXH64_state_t crcOrigState;
1390  XXH64_state_t crcNewState;
1391  const char* dict = testInput + 3;
1392  size_t dictSize = (FUZ_rand(&randState) & 8191);
1393  char* dst = testVerify;
1394 
1395  size_t segStart = dictSize + 7;
1396  size_t segSize = (FUZ_rand(&randState) & 8191);
1397  int segNb = 1;
1398 
1400  LZ4_loadDictHC(&sHC, dict, (int)dictSize);
1401 
1402  XXH64_reset(&crcOrigState, 0);
1403  XXH64_reset(&crcNewState, 0);
1404 
1405  while (segStart + segSize < testInputSize) {
1406  XXH64_hash_t crcOrig;
1407  XXH64_update(&crcOrigState, testInput + segStart, segSize);
1408  crcOrig = XXH64_digest(&crcOrigState);
1409  assert(segSize <= INT_MAX);
1410  result = LZ4_compress_HC_continue(&sHC, testInput + segStart, testCompressed, (int)segSize, LZ4_compressBound((int)segSize));
1411  FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() dictionary compression failed : result = %i", result);
1412  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1413 
1414  result = LZ4_decompress_safe_usingDict(testCompressed, dst, result, (int)segSize, dict, (int)dictSize);
1415  FUZ_CHECKTEST(result!=(int)segSize, "LZ4_decompress_safe_usingDict() dictionary decompression part %i failed", (int)segNb);
1416  XXH64_update(&crcNewState, dst, segSize);
1417  { U64 const crcNew = XXH64_digest(&crcNewState);
1418  if (crcOrig != crcNew) FUZ_findDiff(dst, testInput+segStart);
1419  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_usingDict() part %i corruption", segNb);
1420  }
1421 
1422  dict = dst;
1423  dictSize = segSize;
1424 
1425  dst += segSize + 1;
1426  segNb ++;
1427 
1428  segStart += segSize + (FUZ_rand(&randState) & 0xF) + 1;
1429  segSize = (FUZ_rand(&randState) & 8191);
1430  } }
1431 
1432  /* ring buffer test */
1433  { XXH64_state_t xxhOrig;
1434  XXH64_state_t xxhNewSafe, xxhNewFast;
1435  LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
1436  const U32 maxMessageSizeLog = 10;
1437  const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
1438  U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
1439  U32 iNext = 0;
1440  U32 rNext = 0;
1441  U32 dNext = 0;
1442  const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
1443 
1444  XXH64_reset(&xxhOrig, 0);
1445  XXH64_reset(&xxhNewSafe, 0);
1446  XXH64_reset(&xxhNewFast, 0);
1448  LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
1449  LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
1450 
1451  while (iNext + messageSize < testCompressedSize) {
1452  int compressedSize;
1453  XXH64_hash_t crcOrig;
1454  XXH64_update(&xxhOrig, testInput + iNext, messageSize);
1455  crcOrig = XXH64_digest(&xxhOrig);
1456 
1457  memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
1458  assert(messageSize < INT_MAX);
1459  compressedSize = LZ4_compress_HC_continue(&sHC, ringBuffer + rNext, testCompressed, (int)messageSize, testCompressedSize-ringBufferSize);
1460  FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
1461  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1462 
1463  assert(messageSize < INT_MAX);
1464  result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, (int)messageSize);
1465  FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe_continue() test failed");
1466 
1467  XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
1468  { XXH64_hash_t const crcNew = XXH64_digest(&xxhNewSafe);
1469  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
1470 
1471  assert(messageSize < INT_MAX);
1472  result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, (int)messageSize);
1473  FUZ_CHECKTEST(result!=compressedSize, "ringBuffer : LZ4_decompress_fast_continue() test failed");
1474 
1475  XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
1476  { XXH64_hash_t const crcNew = XXH64_digest(&xxhNewFast);
1477  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
1478 
1479  /* prepare next message */
1480  iNext += messageSize;
1481  rNext += messageSize;
1482  dNext += messageSize;
1483  messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
1484  if (rNext + messageSize > ringBufferSize) rNext = 0;
1485  if (dNext + messageSize > dBufferSize) dNext = 0;
1486  }
1487  }
1488 
1489  /* Ring buffer test : Non synchronized decoder */
1490  /* This test uses minimum amount of memory required to setup a decoding ring buffer
1491  * while being unsynchronized with encoder
1492  * (no assumption done on how the data is encoded, it just follows LZ4 format specification).
1493  * This size is documented in lz4.h, and is LZ4_decoderRingBufferSize(maxBlockSize).
1494  */
1495  { XXH64_state_t xxhOrig;
1496  XXH64_state_t xxhNewSafe, xxhNewFast;
1497  XXH64_hash_t crcOrig;
1498  LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
1499  const int maxMessageSizeLog = 12;
1500  const int maxMessageSize = 1 << maxMessageSizeLog;
1501  const int maxMessageSizeMask = maxMessageSize - 1;
1502  int messageSize;
1503  U32 totalMessageSize = 0;
1504  const int dBufferSize = LZ4_decoderRingBufferSize(maxMessageSize);
1505  char* const ringBufferSafe = testVerify;
1506  char* const ringBufferFast = testVerify + dBufferSize + 1; /* used by LZ4_decompress_fast_continue */
1507  int iNext = 0;
1508  int dNext = 0;
1509  int compressedSize;
1510 
1511  assert((size_t)dBufferSize * 2 + 1 < testInputSize); /* space used by ringBufferSafe and ringBufferFast */
1512  XXH64_reset(&xxhOrig, 0);
1513  XXH64_reset(&xxhNewSafe, 0);
1514  XXH64_reset(&xxhNewFast, 0);
1516  LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
1517  LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
1518 
1519 #define BSIZE1 (dBufferSize - (maxMessageSize-1))
1520 
1521  /* first block */
1522  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. */
1523  XXH64_update(&xxhOrig, testInput + iNext, (size_t)messageSize);
1524  crcOrig = XXH64_digest(&xxhOrig);
1525 
1526  compressedSize = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
1527  FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
1528  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1529 
1530  result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, ringBufferSafe + dNext, compressedSize, messageSize);
1531  FUZ_CHECKTEST(result!=messageSize, "64K D.ringBuffer : LZ4_decompress_safe_continue() test failed");
1532 
1533  XXH64_update(&xxhNewSafe, ringBufferSafe + dNext, (size_t)messageSize);
1534  { U64 const crcNew = XXH64_digest(&xxhNewSafe);
1535  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
1536 
1537  result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, ringBufferFast + dNext, messageSize);
1538  FUZ_CHECKTEST(result!=compressedSize, "64K D.ringBuffer : LZ4_decompress_fast_continue() test failed");
1539 
1540  XXH64_update(&xxhNewFast, ringBufferFast + dNext, (size_t)messageSize);
1541  { U64 const crcNew = XXH64_digest(&xxhNewFast);
1542  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
1543 
1544  /* prepare second message */
1545  dNext += messageSize;
1546  assert(messageSize >= 0);
1547  totalMessageSize += (unsigned)messageSize;
1548  messageSize = maxMessageSize;
1549  iNext = BSIZE1+1;
1550  assert(BSIZE1 >= 65535);
1551  memcpy(testInput + iNext, testInput + (BSIZE1-65535), messageSize); /* will generate a match at max distance == 65535 */
1552  FUZ_CHECKTEST(dNext+messageSize <= dBufferSize, "Ring buffer test : second message should require restarting from beginning");
1553  dNext = 0;
1554 
1555  while (totalMessageSize < 9 MB) {
1556  XXH64_update(&xxhOrig, testInput + iNext, (size_t)messageSize);
1557  crcOrig = XXH64_digest(&xxhOrig);
1558 
1559  compressedSize = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
1560  FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
1561  FUZ_CHECKTEST(sHC.internal_donotuse.dirty, "Context should be clean");
1562  DISPLAYLEVEL(5, "compressed %i bytes to %i bytes \n", messageSize, compressedSize);
1563 
1564  /* test LZ4_decompress_safe_continue */
1565  assert(dNext < dBufferSize);
1566  assert(dBufferSize - dNext >= maxMessageSize);
1567  result = LZ4_decompress_safe_continue(&decodeStateSafe,
1568  testCompressed, ringBufferSafe + dNext,
1569  compressedSize, dBufferSize - dNext); /* works without knowing messageSize, under assumption that messageSize <= maxMessageSize */
1570  FUZ_CHECKTEST(result!=messageSize, "D.ringBuffer : LZ4_decompress_safe_continue() test failed");
1571  XXH64_update(&xxhNewSafe, ringBufferSafe + dNext, (size_t)messageSize);
1572  { U64 const crcNew = XXH64_digest(&xxhNewSafe);
1573  if (crcOrig != crcNew) FUZ_findDiff(testInput + iNext, ringBufferSafe + dNext);
1574  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption during D.ringBuffer test");
1575  }
1576 
1577  /* test LZ4_decompress_fast_continue in its own buffer ringBufferFast */
1578  result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, ringBufferFast + dNext, messageSize);
1579  FUZ_CHECKTEST(result!=compressedSize, "D.ringBuffer : LZ4_decompress_fast_continue() test failed");
1580  XXH64_update(&xxhNewFast, ringBufferFast + dNext, (size_t)messageSize);
1581  { U64 const crcNew = XXH64_digest(&xxhNewFast);
1582  if (crcOrig != crcNew) FUZ_findDiff(testInput + iNext, ringBufferFast + dNext);
1583  FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption during D.ringBuffer test");
1584  }
1585 
1586  /* prepare next message */
1587  dNext += messageSize;
1588  assert(messageSize >= 0);
1589  totalMessageSize += (unsigned)messageSize;
1590  messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
1591  iNext = (FUZ_rand(&randState) & 65535);
1592  if (dNext + maxMessageSize > dBufferSize) dNext = 0;
1593  }
1594  } /* Ring buffer test : Non synchronized decoder */
1595  }
1596 
1597  DISPLAYLEVEL(3, "LZ4_compress_HC_destSize : ");
1598  /* encode congenerical sequence test for HC compressors */
1599  { LZ4_streamHC_t* const sHC = LZ4_createStreamHC();
1600  int const src_buf_size = 3 MB;
1601  int const dst_buf_size = 6 KB;
1602  int const payload = 0;
1603  int const dst_step = 43;
1604  int const dst_min_len = 33 + (FUZ_rand(&randState) % dst_step);
1605  int const dst_max_len = 5000;
1606  int slen, dlen;
1607  char* sbuf1 = (char*)malloc(src_buf_size + 1);
1608  char* sbuf2 = (char*)malloc(src_buf_size + 1);
1609  char* dbuf1 = (char*)malloc(dst_buf_size + 1);
1610  char* dbuf2 = (char*)malloc(dst_buf_size + 1);
1611 
1612  assert(sHC != NULL);
1613  assert(dst_buf_size > dst_max_len);
1614  if (!sbuf1 || !sbuf2 || !dbuf1 || !dbuf2) {
1615  EXIT_MSG("not enough memory for FUZ_unitTests (destSize)");
1616  }
1617  for (dlen = dst_min_len; dlen <= dst_max_len; dlen += dst_step) {
1618  int src_len = (dlen - 10)*255 + 24;
1619  if (src_len + 10 >= src_buf_size) break; /* END of check */
1620  for (slen = src_len - 3; slen <= src_len + 3; slen++) {
1621  int srcsz1, srcsz2;
1622  int dsz1, dsz2;
1623  int res1, res2;
1624  char const endchk = (char)0x88;
1625  DISPLAYLEVEL(5, "slen = %i, ", slen);
1626 
1627  srcsz1 = slen;
1628  memset(sbuf1, payload, slen);
1629  memset(dbuf1, 0, dlen);
1630  dbuf1[dlen] = endchk;
1631  dsz1 = LZ4_compress_destSize(sbuf1, dbuf1, &srcsz1, dlen);
1632  DISPLAYLEVEL(5, "LZ4_compress_destSize: %i bytes compressed into %i bytes, ", srcsz1, dsz1);
1633  DISPLAYLEVEL(5, "last token : 0x%0X, ", dbuf1[dsz1 - 6]);
1634  DISPLAYLEVEL(5, "last ML extra lenbyte : 0x%0X, \n", dbuf1[dsz1 - 7]);
1635  FUZ_CHECKTEST(dbuf1[dlen] != endchk, "LZ4_compress_destSize() overwrite dst buffer !");
1636  FUZ_CHECKTEST(dsz1 <= 0, "LZ4_compress_destSize() compression failed");
1637  FUZ_CHECKTEST(dsz1 > dlen, "LZ4_compress_destSize() result larger than dst buffer !");
1638  FUZ_CHECKTEST(srcsz1 > slen, "LZ4_compress_destSize() read more than src buffer !");
1639 
1640  res1 = LZ4_decompress_safe(dbuf1, sbuf1, dsz1, src_buf_size);
1641  FUZ_CHECKTEST(res1 != srcsz1, "LZ4_compress_destSize() decompression failed!");
1642 
1643  srcsz2 = slen;
1644  memset(sbuf2, payload, slen);
1645  memset(dbuf2, 0, dlen);
1646  dbuf2[dlen] = endchk;
1648  dsz2 = LZ4_compress_HC_destSize(sHC, sbuf2, dbuf2, &srcsz2, dlen, compressionLevel);
1649  DISPLAYLEVEL(5, "LZ4_compress_HC_destSize: %i bytes compressed into %i bytes, ", srcsz2, dsz2);
1650  DISPLAYLEVEL(5, "last token : 0x%0X, ", dbuf2[dsz2 - 6]);
1651  DISPLAYLEVEL(5, "last ML extra lenbyte : 0x%0X, \n", dbuf2[dsz2 - 7]);
1652  FUZ_CHECKTEST(dbuf2[dlen] != endchk, "LZ4_compress_HC_destSize() overwrite dst buffer !");
1653  FUZ_CHECKTEST(dsz2 <= 0, "LZ4_compress_HC_destSize() compression failed");
1654  FUZ_CHECKTEST(dsz2 > dlen, "LZ4_compress_HC_destSize() result larger than dst buffer !");
1655  FUZ_CHECKTEST(srcsz2 > slen, "LZ4_compress_HC_destSize() read more than src buffer !");
1656  FUZ_CHECKTEST(dsz2 != dsz1, "LZ4_compress_HC_destSize() return incorrect result !");
1657  FUZ_CHECKTEST(srcsz2 != srcsz1, "LZ4_compress_HC_destSize() return incorrect src buffer size "
1658  ": srcsz2(%i) != srcsz1(%i)", srcsz2, srcsz1);
1659  FUZ_CHECKTEST(memcmp(dbuf2, dbuf1, (size_t)dsz2), "LZ4_compress_HC_destSize() return incorrect data into dst buffer !");
1660 
1661  res2 = LZ4_decompress_safe(dbuf2, sbuf1, dsz2, src_buf_size);
1662  FUZ_CHECKTEST(res2 != srcsz1, "LZ4_compress_HC_destSize() decompression failed!");
1663 
1664  FUZ_CHECKTEST(memcmp(sbuf1, sbuf2, (size_t)res2), "LZ4_compress_HC_destSize() decompression corruption!");
1665  }
1666  }
1667  LZ4_freeStreamHC(sHC);
1668  free(sbuf1);
1669  free(sbuf2);
1670  free(dbuf1);
1671  free(dbuf2);
1672  }
1673  DISPLAYLEVEL(3, " OK \n");
1674 
1675 
1676  /* clean up */
1677  free(testInput);
1678  free(testCompressed);
1679  free(testVerify);
1680 
1681  printf("All unit tests completed successfully compressionLevel=%d \n", compressionLevel);
1682  return;
1683 }
#define INT_MAX
Definition: cp-demangle.c:131
#define testCompressedSize
Definition: fuzzer.c:1013
static int FUZ_AddressOverflow(void)
Definition: fuzzer.c:183
#define BSIZE1
#define MB
Definition: fuzzer.c:87
#define testInputSize
Definition: fuzzer.c:1012
#define ringBufferSize
Definition: fuzzer.c:1014
return memset(p, 0, total)
XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *state_in, const void *input, size_t len)
Definition: xxhash.c:971
XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed)
Definition: xxhash.c:898
XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
Definition: xxhash.c:855
XXH_PUBLIC_API unsigned long long XXH64_digest(const XXH64_state_t *state_in)
Definition: xxhash.c:1005
struct XXH64_state_s XXH64_state_t
Definition: xxhash.h:229
unsigned long long XXH64_hash_t
Definition: xxhash.h:219
unsigned int XXH32_hash_t
Definition: xxhash.h:162
unsigned long long U64
Definition: lz4.c:290
LZ4_stream_t * LZ4_createStream(void)
Definition: lz4.c:1423
int LZ4_decoderRingBufferSize(int maxBlockSize)
Definition: lz4.c:2306
LZ4_FORCE_O2 int LZ4_decompress_fast_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *source, char *dest, int originalSize)
Definition: lz4.c:2362
int LZ4_freeStream(LZ4_stream_t *LZ4_stream)
Definition: lz4.c:1465
int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode, const char *dictionary, int dictSize)
Definition: lz4.c:2285
LZ4_FORCE_O2 int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *source, char *dest, int compressedSize, int maxOutputSize)
Definition: lz4.c:2322
int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize)
Definition: lz4.c:1668
#define LZ4_COMPRESSBOUND(isize)
Definition: lz4.h:171
char * dst
Definition: lz4.h:724
int LZ4_saveDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize)
Definition: lz4hc.c:1158
LZ4_streamHC_t * LZ4_initStreamHC(void *buffer, size_t size)
Definition: lz4hc.c:1003
void LZ4_resetStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1021
#define c(i)
Definition: sha256.c:43
static int sp
Definition: z80asm.c:91

References assert(), BSIZE1, c, compressedSize, compressionLevel, test_evm::cs, LZ4HC_CCtx_internal::dirty, DISPLAYLEVEL, dst, EXIT_MSG, free(), FUZ_AddressOverflow(), FUZ_CHECKTEST, FUZ_fillCompressibleNoiseBuffer(), FUZ_findDiff(), FUZ_rand(), int, INT_MAX, LZ4_streamHC_u::internal_donotuse, KB, LZ4_compress_default(), LZ4_compress_destSize(), LZ4_compress_fast_continue(), LZ4_compress_HC_continue(), LZ4_compress_HC_destSize(), LZ4_compressBound(), LZ4_COMPRESSBOUND, LZ4_createStream(), LZ4_createStreamHC(), LZ4_decoderRingBufferSize(), LZ4_decompress_fast_continue(), LZ4_decompress_safe(), LZ4_decompress_safe_continue(), LZ4_decompress_safe_usingDict(), LZ4_freeStream(), LZ4_freeStreamHC(), LZ4_initStream(), LZ4_initStreamHC(), LZ4_loadDictHC(), LZ4_resetStream_fast(), LZ4_resetStreamHC(), LZ4_resetStreamHC_fast(), LZ4_saveDict(), LZ4_saveDictHC(), LZ4_setCompressionLevel(), LZ4_setStreamDecode(), malloc(), MB, memcpy(), memset(), NULL, printf(), r, ringBufferSize, sp, srcSize, testCompressedSize, testInputSize, autogen_x86imm::tmp, unsigned, XXH32(), XXH64(), XXH64_digest(), XXH64_reset(), and XXH64_update().

Referenced by main().

◆ FUZ_usage()

static int FUZ_usage ( const char *  programName)
static

Definition at line 1691 of file fuzzer.c.

1692 {
1693  DISPLAY( "Usage :\n");
1694  DISPLAY( " %s [args]\n", programName);
1695  DISPLAY( "\n");
1696  DISPLAY( "Arguments :\n");
1697  DISPLAY( " -i# : Nb of tests (default:%i) \n", NB_ATTEMPTS);
1698  DISPLAY( " -T# : Duration of tests, in seconds (default: use Nb of tests) \n");
1699  DISPLAY( " -s# : Select seed (default:prompt user)\n");
1700  DISPLAY( " -t# : Select starting test number (default:0)\n");
1701  DISPLAY( " -P# : Select compressibility in %% (default:%i%%)\n", FUZ_COMPRESSIBILITY_DEFAULT);
1702  DISPLAY( " -v : verbose\n");
1703  DISPLAY( " -p : pause at the end\n");
1704  DISPLAY( " -h : display help and exit\n");
1705  return 0;
1706 }
#define NB_ATTEMPTS
Definition: fuzzer.c:77
#define FUZ_COMPRESSIBILITY_DEFAULT
Definition: fuzzer.c:81

References DISPLAY, FUZ_COMPRESSIBILITY_DEFAULT, and NB_ATTEMPTS.

Referenced by main().

◆ main()

int main ( int  argc,
const char **  argv 
)

Definition at line 1709 of file fuzzer.c.

1710 {
1711  U32 seed = 0;
1712  int seedset = 0;
1713  int argNb;
1714  unsigned nbTests = NB_ATTEMPTS;
1715  unsigned testNb = 0;
1716  int proba = FUZ_COMPRESSIBILITY_DEFAULT;
1717  int use_pause = 0;
1718  const char* programName = argv[0];
1719  U32 duration = 0;
1720 
1721  /* Check command line */
1722  for(argNb=1; argNb<argc; argNb++) {
1723  const char* argument = argv[argNb];
1724 
1725  if(!argument) continue; // Protection if argument empty
1726 
1727  // Decode command (note : aggregated commands are allowed)
1728  if (argument[0]=='-') {
1729  if (!strcmp(argument, "--no-prompt")) { use_pause=0; seedset=1; g_displayLevel=1; continue; }
1730  argument++;
1731 
1732  while (*argument!=0) {
1733  switch(*argument)
1734  {
1735  case 'h': /* display help */
1736  return FUZ_usage(programName);
1737 
1738  case 'v': /* verbose mode */
1739  g_displayLevel++;
1740  argument++;
1741  break;
1742 
1743  case 'p': /* pause at the end */
1744  use_pause=1;
1745  argument++;
1746  break;
1747 
1748  case 'i':
1749  argument++;
1750  nbTests = 0; duration = 0;
1751  while ((*argument>='0') && (*argument<='9')) {
1752  nbTests *= 10;
1753  nbTests += (unsigned)(*argument - '0');
1754  argument++;
1755  }
1756  break;
1757 
1758  case 'T':
1759  argument++;
1760  nbTests = 0; duration = 0;
1761  for (;;) {
1762  switch(*argument)
1763  {
1764  case 'm': duration *= 60; argument++; continue;
1765  case 's':
1766  case 'n': argument++; continue;
1767  case '0':
1768  case '1':
1769  case '2':
1770  case '3':
1771  case '4':
1772  case '5':
1773  case '6':
1774  case '7':
1775  case '8':
1776  case '9': duration *= 10; duration += (U32)(*argument++ - '0'); continue;
1777  }
1778  break;
1779  }
1780  break;
1781 
1782  case 's':
1783  argument++;
1784  seed=0; seedset=1;
1785  while ((*argument>='0') && (*argument<='9')) {
1786  seed *= 10;
1787  seed += (U32)(*argument - '0');
1788  argument++;
1789  }
1790  break;
1791 
1792  case 't': /* select starting test nb */
1793  argument++;
1794  testNb=0;
1795  while ((*argument>='0') && (*argument<='9')) {
1796  testNb *= 10;
1797  testNb += (unsigned)(*argument - '0');
1798  argument++;
1799  }
1800  break;
1801 
1802  case 'P': /* change probability */
1803  argument++;
1804  proba=0;
1805  while ((*argument>='0') && (*argument<='9')) {
1806  proba *= 10;
1807  proba += *argument - '0';
1808  argument++;
1809  }
1810  if (proba<0) proba=0;
1811  if (proba>100) proba=100;
1812  break;
1813  default: ;
1814  }
1815  }
1816  }
1817  }
1818 
1819  printf("Starting LZ4 fuzzer (%i-bits, v%s)\n", (int)(sizeof(size_t)*8), LZ4_versionString());
1820 
1821  if (!seedset) {
1822  time_t const t = time(NULL);
1823  U32 const h = XXH32(&t, sizeof(t), 1);
1824  seed = h % 10000;
1825  }
1826  printf("Seed = %u\n", seed);
1827 
1828  if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) printf("Compressibility : %i%%\n", proba);
1829 
1830  if ((seedset==0) && (testNb==0)) { FUZ_unitTests(LZ4HC_CLEVEL_DEFAULT); FUZ_unitTests(LZ4HC_CLEVEL_OPT_MIN); }
1831 
1832  nbTests += (nbTests==0); /* avoid zero */
1833 
1834  { int const result = FUZ_test(seed, nbTests, testNb, ((double)proba) / 100, duration);
1835  if (use_pause) {
1836  DISPLAY("press enter ... \n");
1837  (void)getchar();
1838  }
1839  return result;
1840  }
1841 }
static U32 use_pause
Definition: checkFrame.c:82
static int FUZ_usage(const char *programName)
Definition: fuzzer.c:1691
static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double compressibility, U32 duration_s)
Definition: fuzzer.c:316
static void FUZ_unitTests(int compressionLevel)
Definition: fuzzer.c:1016
static static fork const void static count static fd const char const char static newpath char char char static envp time
Definition: sflib.h:42
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
const char * LZ4_versionString(void)
Definition: lz4.c:673
#define LZ4HC_CLEVEL_OPT_MIN
Definition: lz4hc.h:49
#define LZ4HC_CLEVEL_DEFAULT
Definition: lz4hc.h:48
int time_t
Definition: sftypes.h:66
#define h(i)
Definition: sha256.c:48

References argv, DISPLAY, FUZ_COMPRESSIBILITY_DEFAULT, FUZ_test(), FUZ_unitTests(), FUZ_usage(), g_displayLevel, h, LZ4_versionString(), LZ4HC_CLEVEL_DEFAULT, LZ4HC_CLEVEL_OPT_MIN, NB_ATTEMPTS, NULL, printf(), time, U32, unsigned, use_pause, and XXH32().

Variable Documentation

◆ g_displayLevel

int g_displayLevel = 2
static

Definition at line 96 of file fuzzer.c.

Referenced by FUZ_displayUpdate(), and main().