[fuzz] Speed up round trip tests

* Enforce smaller maximum values for parameters
* Adjust parameters to the source size

The memory usage is reduced by about 5x, which makes the fuzzers run at
least twice as fast, even more so with ASAN/MSAN enabled.
This commit is contained in:
Nick Terrell
2017-09-26 14:03:43 -07:00
parent 8a4d0abc1c
commit 471aa385b3
5 changed files with 80 additions and 46 deletions
+11 -18
View File
@@ -34,27 +34,20 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
void *compressed, size_t compressedCapacity, void *compressed, size_t compressedCapacity,
const void *src, size_t srcSize) const void *src, size_t srcSize)
{ {
int const cLevel = FUZZ_rand(&seed) % kMaxClevel; int const cLevel = FUZZ_rand(&seed) % kMaxClevel;
size_t ret = ZSTD_compressBegin(cctx, cLevel); ZSTD_parameters const params = ZSTD_getParams(cLevel, srcSize, 0);
size_t ret = ZSTD_compressBegin_advanced(cctx, NULL, 0, params, srcSize);
FUZZ_ZASSERT(ret);
if (ZSTD_isError(ret)) { ret = ZSTD_compressBlock(cctx, compressed, compressedCapacity, src, srcSize);
fprintf(stderr, "ZSTD_compressBegin() error: %s\n", FUZZ_ZASSERT(ret);
ZSTD_getErrorName(ret)); if (ret == 0) {
return ret;
}
ret = ZSTD_compressBlock(cctx, compressed, compressedCapacity, src, srcSize);
if (ZSTD_isError(ret)) {
fprintf(stderr, "ZSTD_compressBlock() error: %s\n", ZSTD_getErrorName(ret));
return ret;
}
if (ret == 0) {
FUZZ_ASSERT(resultCapacity >= srcSize); FUZZ_ASSERT(resultCapacity >= srcSize);
memcpy(result, src, srcSize); memcpy(result, src, srcSize);
return srcSize; return srcSize;
} }
ZSTD_decompressBegin(dctx); ZSTD_decompressBegin(dctx);
return ZSTD_decompressBlock(dctx, result, resultCapacity, compressed, ret); return ZSTD_decompressBlock(dctx, result, resultCapacity, compressed, ret);
} }
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
@@ -87,7 +80,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
size_t const result = size_t const result =
roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size); roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size);
FUZZ_ASSERT_MSG(!ZSTD_isError(result), ZSTD_getErrorName(result)); FUZZ_ZASSERT(result);
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
} }
+5 -9
View File
@@ -41,21 +41,17 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
size_t err; size_t err;
ZSTD_CCtx_reset(cctx); ZSTD_CCtx_reset(cctx);
FUZZ_setRandomParameters(cctx, &seed); FUZZ_setRandomParameters(cctx, srcSize, &seed);
err = ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end); err = ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end);
if (err != 0) { FUZZ_ZASSERT(err);
return err; FUZZ_ASSERT(err == 0);
}
cSize = out.pos; cSize = out.pos;
} else { } else {
int const cLevel = FUZZ_rand(&seed) % kMaxClevel; int const cLevel = FUZZ_rand(&seed) % kMaxClevel;
cSize = ZSTD_compressCCtx( cSize = ZSTD_compressCCtx(
cctx, compressed, compressedCapacity, src, srcSize, cLevel); cctx, compressed, compressedCapacity, src, srcSize, cLevel);
} }
if (ZSTD_isError(cSize)) { FUZZ_ZASSERT(cSize);
fprintf(stderr, "Compression error: %s\n", ZSTD_getErrorName(cSize));
return cSize;
}
return ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize); return ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize);
} }
@@ -87,7 +83,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
size_t const result = size_t const result =
roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size); roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size);
FUZZ_ASSERT_MSG(!ZSTD_isError(result), ZSTD_getErrorName(result)); FUZZ_ZASSERT(result);
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
} }
+6 -3
View File
@@ -57,7 +57,7 @@ static size_t compress(uint8_t *dst, size_t capacity,
{ {
size_t dstSize = 0; size_t dstSize = 0;
ZSTD_CCtx_reset(cctx); ZSTD_CCtx_reset(cctx);
FUZZ_setRandomParameters(cctx, &seed); FUZZ_setRandomParameters(cctx, srcSize, &seed);
while (srcSize > 0) { while (srcSize > 0) {
ZSTD_inBuffer in = makeInBuffer(&src, &srcSize); ZSTD_inBuffer in = makeInBuffer(&src, &srcSize);
@@ -85,7 +85,10 @@ static size_t compress(uint8_t *dst, size_t capacity,
/* Reset the compressor when the frame is finished */ /* Reset the compressor when the frame is finished */
if (ret == 0) { if (ret == 0) {
ZSTD_CCtx_reset(cctx); ZSTD_CCtx_reset(cctx);
FUZZ_setRandomParameters(cctx, &seed); if ((FUZZ_rand(&seed) & 7) == 0) {
size_t const remaining = in.size - in.pos;
FUZZ_setRandomParameters(cctx, remaining, &seed);
}
mode = -1; mode = -1;
} }
break; break;
@@ -146,7 +149,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
size_t const cSize = compress(cBuf, neededBufSize, src, size); size_t const cSize = compress(cBuf, neededBufSize, src, size);
size_t const rSize = size_t const rSize =
ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize); ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize);
FUZZ_ASSERT_MSG(!ZSTD_isError(rSize), ZSTD_getErrorName(rSize)); FUZZ_ZASSERT(rSize);
FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
} }
+53 -15
View File
@@ -13,30 +13,68 @@
#include "fuzz_helpers.h" #include "fuzz_helpers.h"
#include "zstd.h" #include "zstd.h"
static void setRand(ZSTD_CCtx *cctx, ZSTD_cParameter param, unsigned min, static void set(ZSTD_CCtx *cctx, ZSTD_cParameter param, unsigned value)
unsigned max, uint32_t *state) { {
unsigned const value = FUZZ_rand32(state, min, max); FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, param, value));
FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, param, value));
} }
void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, uint32_t *state) static void setRand(ZSTD_CCtx *cctx, ZSTD_cParameter param, unsigned min,
unsigned max, uint32_t *state) {
unsigned const value = FUZZ_rand32(state, min, max);
set(cctx, param, value);
}
ZSTD_compressionParameters FUZZ_randomCParams(size_t srcSize, uint32_t *state)
{ {
setRand(cctx, ZSTD_p_windowLog, ZSTD_WINDOWLOG_MIN, 23, state); /* Select compression parameters */
setRand(cctx, ZSTD_p_hashLog, ZSTD_HASHLOG_MIN, 23, state); ZSTD_compressionParameters cParams;
setRand(cctx, ZSTD_p_chainLog, ZSTD_CHAINLOG_MIN, 24, state); cParams.windowLog = FUZZ_rand32(state, ZSTD_WINDOWLOG_MIN, 15);
setRand(cctx, ZSTD_p_searchLog, ZSTD_SEARCHLOG_MIN, 9, state); cParams.hashLog = FUZZ_rand32(state, ZSTD_HASHLOG_MIN, 15);
setRand(cctx, ZSTD_p_minMatch, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX, cParams.chainLog = FUZZ_rand32(state, ZSTD_CHAINLOG_MIN, 16);
state); cParams.searchLog = FUZZ_rand32(state, ZSTD_SEARCHLOG_MIN, 9);
setRand(cctx, ZSTD_p_targetLength, ZSTD_TARGETLENGTH_MIN, cParams.searchLength = FUZZ_rand32(state, ZSTD_SEARCHLENGTH_MIN,
ZSTD_TARGETLENGTH_MAX, state); ZSTD_SEARCHLENGTH_MAX);
setRand(cctx, ZSTD_p_compressionStrategy, ZSTD_fast, ZSTD_btultra, state); cParams.targetLength = FUZZ_rand32(state, ZSTD_TARGETLENGTH_MIN,
ZSTD_TARGETLENGTH_MAX);
cParams.strategy = FUZZ_rand32(state, ZSTD_fast, ZSTD_btultra);
return ZSTD_adjustCParams(cParams, srcSize, 0);
}
ZSTD_frameParameters FUZZ_randomFParams(uint32_t *state)
{
/* Select frame parameters */
ZSTD_frameParameters fParams;
fParams.contentSizeFlag = FUZZ_rand32(state, 0, 1);
fParams.checksumFlag = FUZZ_rand32(state, 0, 1);
fParams.noDictIDFlag = FUZZ_rand32(state, 0, 1);
return fParams;
}
ZSTD_parameters FUZZ_randomParams(size_t srcSize, uint32_t *state)
{
ZSTD_parameters params;
params.cParams = FUZZ_randomCParams(srcSize, state);
params.fParams = FUZZ_randomFParams(state);
return params;
}
void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, uint32_t *state)
{
ZSTD_compressionParameters cParams = FUZZ_randomCParams(srcSize, state);
set(cctx, ZSTD_p_windowLog, cParams.windowLog);
set(cctx, ZSTD_p_hashLog, cParams.hashLog);
set(cctx, ZSTD_p_chainLog, cParams.chainLog);
set(cctx, ZSTD_p_searchLog, cParams.searchLog);
set(cctx, ZSTD_p_minMatch, cParams.searchLength);
set(cctx, ZSTD_p_targetLength, cParams.targetLength);
set(cctx, ZSTD_p_compressionStrategy, cParams.strategy);
/* Select frame parameters */ /* Select frame parameters */
setRand(cctx, ZSTD_p_contentSizeFlag, 0, 1, state); setRand(cctx, ZSTD_p_contentSizeFlag, 0, 1, state);
setRand(cctx, ZSTD_p_checksumFlag, 0, 1, state); setRand(cctx, ZSTD_p_checksumFlag, 0, 1, state);
setRand(cctx, ZSTD_p_dictIDFlag, 0, 1, state); setRand(cctx, ZSTD_p_dictIDFlag, 0, 1, state);
/* Select long distance matchig parameters */ /* Select long distance matchig parameters */
setRand(cctx, ZSTD_p_enableLongDistanceMatching, 0, 1, state); setRand(cctx, ZSTD_p_enableLongDistanceMatching, 0, 1, state);
setRand(cctx, ZSTD_p_ldmHashLog, ZSTD_HASHLOG_MIN, 24, state); setRand(cctx, ZSTD_p_ldmHashLog, ZSTD_HASHLOG_MIN, 16, state);
setRand(cctx, ZSTD_p_ldmMinMatch, ZSTD_LDM_MINMATCH_MIN, setRand(cctx, ZSTD_p_ldmMinMatch, ZSTD_LDM_MINMATCH_MIN,
ZSTD_LDM_MINMATCH_MAX, state); ZSTD_LDM_MINMATCH_MAX, state);
setRand(cctx, ZSTD_p_ldmBucketSizeLog, 0, ZSTD_LDM_BUCKETSIZELOG_MAX, setRand(cctx, ZSTD_p_ldmBucketSizeLog, 0, ZSTD_LDM_BUCKETSIZELOG_MAX,
+5 -1
View File
@@ -21,7 +21,11 @@
extern "C" { extern "C" {
#endif #endif
void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, uint32_t *state); void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, uint32_t *state);
ZSTD_compressionParameters FUZZ_randomCParams(size_t srcSize, uint32_t *state);
ZSTD_frameParameters FUZZ_randomFParams(uint32_t *state);
ZSTD_parameters FUZZ_randomParams(size_t srcSize, uint32_t *state);
#ifdef __cplusplus #ifdef __cplusplus