static void FUZ_tests (U32 seed, U32 totalTest, U32 startTestNb) { BYTE* bufferP0 = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferP1 = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferP15 = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferP90 = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferP100 = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferDst = (BYTE*) malloc (BUFFERSIZE+64); BYTE* bufferVerif = (BYTE*) malloc (BUFFERSIZE+64); size_t const bufferDstSize = BUFFERSIZE+64; unsigned testNb; size_t const maxTestSizeMask = 0x1FFFF; /* 128 KB - 1 */ U32 rootSeed = seed; U32 time = FUZ_GetMilliStart(); generateNoise (bufferP0, BUFFERSIZE, &rootSeed); generate (bufferP1 , BUFFERSIZE, 0.01, &rootSeed); generate (bufferP15 , BUFFERSIZE, 0.15, &rootSeed); generate (bufferP90 , BUFFERSIZE, 0.90, &rootSeed); memset(bufferP100, (BYTE)FUZ_rand(&rootSeed), BUFFERSIZE); memset(bufferDst, 0, BUFFERSIZE); { U32 u; for (u=0; u<startTestNb; u++) FUZ_rand (&rootSeed); } for (testNb=startTestNb; testNb<totalTest; testNb++) { U32 roundSeed = rootSeed ^ 0xEDA5B371; FUZ_rand(&rootSeed); int tag=0; BYTE* bufferTest = NULL; DISPLAYLEVEL (4, "\r test %5u ", testNb); if (FUZ_GetMilliSpan (time) > FUZ_UPDATERATE) { DISPLAY ("\r test %5u ", testNb); time = FUZ_GetMilliStart(); } /* Compression / Decompression tests */ DISPLAYLEVEL (4,"%3i ", tag++); { /* determine test sample */ size_t const sizeOrig = (FUZ_rand(&roundSeed) & maxTestSizeMask) + 1; size_t const offset = (FUZ_rand(&roundSeed) % (BUFFERSIZE - 64 - maxTestSizeMask)); size_t sizeCompressed; U32 hashOrig; if (FUZ_rand(&roundSeed) & 7) bufferTest = bufferP15 + offset; else { switch(FUZ_rand(&roundSeed) & 3) { case 0: bufferTest = bufferP0 + offset; break; case 1: bufferTest = bufferP1 + offset; break; case 2: bufferTest = bufferP90 + offset; break; default : bufferTest = bufferP100 + offset; break; } } hashOrig = XXH32 (bufferTest, sizeOrig, 0); /* compression test */ sizeCompressed = HUF_compress (bufferDst, bufferDstSize, bufferTest, sizeOrig); CHECK(HUF_isError(sizeCompressed), "HUF_compress failed"); if (sizeCompressed > 1) { /* don't check uncompressed & rle corner cases */ /* failed compression test */ { BYTE const saved = bufferVerif[sizeCompressed-1] = 253; size_t const errorCode = HUF_compress (bufferVerif, sizeCompressed-1, bufferTest, sizeOrig); CHECK(errorCode!=0, "HUF_compress should have failed (too small destination buffer)") CHECK(bufferVerif[sizeCompressed-1] != saved, "HUF_compress w/ too small dst : bufferVerif overflow"); } /* decompression test */ { BYTE const saved = bufferVerif[sizeOrig] = 253; size_t const result = HUF_decompress (bufferVerif, sizeOrig, bufferDst, sizeCompressed); CHECK(bufferVerif[sizeOrig] != saved, "HUF_decompress : bufferVerif overflow"); CHECK(HUF_isError(result), "HUF_decompress failed : %s", HUF_getErrorName(result)); { U32 const hashEnd = XXH32 (bufferVerif, sizeOrig, 0); if (hashEnd!=hashOrig) findDifferentByte(bufferVerif, sizeOrig, bufferTest, sizeOrig); CHECK(hashEnd != hashOrig, "HUF_decompress : Decompressed data corrupted"); } } /* quad decoder test (more fragile) */ /* if (sizeOrig > 64) { BYTE const saved = bufferVerif[sizeOrig] = 253; size_t const result = HUF_decompress4X6 (bufferVerif, sizeOrig, bufferDst, sizeCompressed); CHECK(bufferVerif[sizeOrig] != saved, "HUF_decompress4X6 : bufferVerif overflow"); CHECK(HUF_isError(result), "HUF_decompress4X6 failed : %s", HUF_getErrorName(result)); { U32 const hashEnd = XXH32 (bufferVerif, sizeOrig, 0); if (hashEnd!=hashOrig) findDifferentByte(bufferVerif, sizeOrig, bufferTest, sizeOrig); CHECK(hashEnd != hashOrig, "HUF_decompress4X6 : Decompressed data corrupted"); } } */ /* truncated src decompression test */ if (sizeCompressed>4) { /* note : in some rare cases, the truncated bitStream may still generate by chance a valid output of correct size */ size_t const missing = (FUZ_rand(&roundSeed) % (sizeCompressed-3)) + 2; /* no problem, as sizeCompressed > 4 */ size_t const tooSmallSize = sizeCompressed - missing; void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch read overflows */ CHECK(cBufferTooSmall == NULL, "not enough memory !"); memcpy(cBufferTooSmall, bufferDst, tooSmallSize); { size_t const errorCode = HUF_decompress(bufferVerif, sizeOrig, cBufferTooSmall, tooSmallSize); CHECK(!HUF_isError(errorCode) && (errorCode!=sizeOrig), "HUF_decompress should have failed ! (truncated src buffer)"); } free(cBufferTooSmall); } } } /* Compression / Decompression tests */ /* Attempt decompression on bogus data */ { size_t const maxDstSize = FUZ_rand (&roundSeed) & maxTestSizeMask; size_t const sizeCompressed = FUZ_rand (&roundSeed) & maxTestSizeMask; BYTE const saved = (bufferDst[maxDstSize] = 253); size_t result; DISPLAYLEVEL (4,"\b\b\b\b%3i ", tag++);; result = HUF_decompress (bufferDst, maxDstSize, bufferTest, sizeCompressed); CHECK(!HUF_isError(result) && (result > maxDstSize), "Decompression overran output buffer"); CHECK(bufferDst[maxDstSize] != saved, "HUF_decompress noise : bufferDst overflow"); } } /* for (testNb=startTestNb; testNb<totalTest; testNb++) */ /* exit */ free (bufferP0); free (bufferP1); free (bufferP15); free (bufferP90); free (bufferP100); free (bufferDst); free (bufferVerif); }
FORCE_INLINE int Lizard_writeStream(int useHuff, Lizard_stream_t* ctx, BYTE* streamPtr, uint32_t streamLen, BYTE** op, BYTE* oend) { if (useHuff && streamLen > 1024) { #ifndef LIZARD_NO_HUFFMAN int useHuffBuf; if (*op + 6 > oend) { LIZARD_LOG_COMPRESS("*op[%p] + 6 > oend[%p]\n", *op, oend); return -1; } useHuffBuf = ((size_t)(oend - (*op + 6)) < HUF_compressBound(streamLen)); if (useHuffBuf) { if (streamLen > LIZARD_BLOCK_SIZE) { LIZARD_LOG_COMPRESS("streamLen[%d] > LIZARD_BLOCK_SIZE\n", streamLen); return -1; } ctx->comprStreamLen = (U32)HUF_compress(ctx->huffBase, ctx->huffEnd - ctx->huffBase, streamPtr, streamLen); } else { ctx->comprStreamLen = (U32)HUF_compress(*op + 6, oend - (*op + 6), streamPtr, streamLen); } if (!HUF_isError(ctx->comprStreamLen)) { if (ctx->comprStreamLen > 0 && (LIZARD_MINIMAL_HUFF_GAIN(ctx->comprStreamLen) < streamLen)) { /* compressible */ MEM_writeLE24(*op, streamLen); MEM_writeLE24(*op+3, ctx->comprStreamLen); if (useHuffBuf) { if ((size_t)(oend - (*op + 6)) < ctx->comprStreamLen) { LIZARD_LOG_COMPRESS("*op[%p] oend[%p] comprStreamLen[%d]\n", *op, oend, (int)ctx->comprStreamLen); return -1; } memcpy(*op + 6, ctx->huffBase, ctx->comprStreamLen); } *op += ctx->comprStreamLen + 6; LIZARD_LOG_COMPRESS("HUF_compress streamLen=%d comprStreamLen=%d\n", (int)streamLen, (int)ctx->comprStreamLen); return 1; } else { LIZARD_LOG_COMPRESS("HUF_compress ERROR comprStreamLen=%d streamLen=%d\n", (int)ctx->comprStreamLen, (int)streamLen); } } else { LIZARD_LOG_COMPRESS("HUF_compress ERROR %d: %s\n", (int)ctx->comprStreamLen, HUF_getErrorName(ctx->comprStreamLen)); } #else LIZARD_LOG_COMPRESS("compiled with LIZARD_NO_HUFFMAN\n"); (void)ctx; return -1; #endif } else ctx->comprStreamLen = 0; if (*op + 3 + streamLen > oend) { LIZARD_LOG_COMPRESS("*op[%p] + 3 + streamLen[%d] > oend[%p]\n", *op, streamLen, oend); return -1; } MEM_writeLE24(*op, streamLen); *op += 3; memcpy(*op, streamPtr, streamLen); *op += streamLen; LIZARD_LOG_COMPRESS("Uncompressed streamLen=%d\n", (int)streamLen); return 0; }