diff --git a/tests/fuzz/block_round_trip.c b/tests/fuzz/block_round_trip.c index 326d5b247..9ead57a5a 100644 --- a/tests/fuzz/block_round_trip.c +++ b/tests/fuzz/block_round_trip.c @@ -52,9 +52,13 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); + int cLevel = FUZZ_dataProducer_uint32(producer) % kMaxClevel; - size = FUZZ_dataProducer_remainingBytes(producer); size_t neededBufSize = size; if (size > ZSTD_BLOCKSIZE_MAX) diff --git a/tests/fuzz/dictionary_decompress.c b/tests/fuzz/dictionary_decompress.c index 5f660ac52..54903f1f6 100644 --- a/tests/fuzz/dictionary_decompress.c +++ b/tests/fuzz/dictionary_decompress.c @@ -24,7 +24,12 @@ static ZSTD_DCtx *dctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); + FUZZ_dict_t dict; ZSTD_DDict* ddict = NULL; int i; @@ -43,8 +48,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1), (ZSTD_dictContentType_e)FUZZ_dataProducer_uint32Range(producer, 0, 2))); } - /* Run it 10 times over 10 output sizes. Reuse the context and dict. */ - for (i = 0; i < 10; ++i) { + + { size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 2 * size); void* rBuf = malloc(bufSize); FUZZ_ASSERT(rBuf); diff --git a/tests/fuzz/dictionary_round_trip.c b/tests/fuzz/dictionary_round_trip.c index fe0a217b2..cd1ca38f7 100644 --- a/tests/fuzz/dictionary_round_trip.c +++ b/tests/fuzz/dictionary_round_trip.c @@ -68,13 +68,16 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); + size_t const rBufSize = size; void* rBuf = malloc(rBufSize); size_t cBufSize = ZSTD_compressBound(size); - void* cBuf; - - FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); - + void *cBuf; /* Half of the time fuzz with a 1 byte smaller output size. * This will still succeed because we force the checksum to be disabled, * giving us 4 bytes of overhead. diff --git a/tests/fuzz/simple_compress.c b/tests/fuzz/simple_compress.c index 29de4701f..b8c6394cb 100644 --- a/tests/fuzz/simple_compress.c +++ b/tests/fuzz/simple_compress.c @@ -24,14 +24,17 @@ static ZSTD_CCtx *cctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); - int const level = (int)FUZZ_dataProducer_uint32Range( - producer, 0, 19 + 3) - 3; /* [-3, 19] */ size_t const maxSize = ZSTD_compressBound(size); size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, maxSize); - size = FUZZ_dataProducer_remainingBytes(producer); + int const level = (int)FUZZ_dataProducer_uint32Range( + producer, 0, 19 + 3) - 3; /* [-3, 19] */ if (!cctx) { cctx = ZSTD_createCCtx(); diff --git a/tests/fuzz/simple_decompress.c b/tests/fuzz/simple_decompress.c index 0ab634fa0..5c7680bf0 100644 --- a/tests/fuzz/simple_decompress.c +++ b/tests/fuzz/simple_decompress.c @@ -23,25 +23,25 @@ static ZSTD_DCtx *dctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { - FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); - if (!dctx) { - dctx = ZSTD_createDCtx(); - FUZZ_ASSERT(dctx); - } + if (!dctx) { + dctx = ZSTD_createDCtx(); + FUZZ_ASSERT(dctx); + } - size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size); - void *rBuf = malloc(bufSize); - FUZZ_ASSERT(rBuf); + size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size); + void *rBuf = malloc(bufSize); + FUZZ_ASSERT(rBuf); - /* Restrict to remaining data. If we run out of data while generating params, - we should still continue and let decompression happen on empty data. */ - size = FUZZ_dataProducer_remainingBytes(producer); + ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size); + free(rBuf); - ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size); - free(rBuf); - - FUZZ_dataProducer_free(producer); + FUZZ_dataProducer_free(producer); #ifndef STATEFUL_FUZZING ZSTD_freeDCtx(dctx); dctx = NULL; diff --git a/tests/fuzz/simple_round_trip.c b/tests/fuzz/simple_round_trip.c index b88d404f9..f19e37a35 100644 --- a/tests/fuzz/simple_round_trip.c +++ b/tests/fuzz/simple_round_trip.c @@ -52,12 +52,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) size_t cBufSize = ZSTD_compressBound(size); void* cBuf; + /* Give a random portion of src data to the producer, to use for + parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); + size = FUZZ_dataProducer_contract(producer, producerSliceSize); + /* Half of the time fuzz with a 1 byte smaller output size. * This will still succeed because we don't use a dictionary, so the dictID * field is empty, giving us 4 bytes of overhead. */ cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1); + size = FUZZ_dataProducer_remainingBytes(producer); + cBuf = malloc(cBufSize); FUZZ_ASSERT(cBuf && rBuf); diff --git a/tests/fuzz/stream_round_trip.c b/tests/fuzz/stream_round_trip.c index 4569222f1..02bb26daa 100644 --- a/tests/fuzz/stream_round_trip.c +++ b/tests/fuzz/stream_round_trip.c @@ -125,15 +125,15 @@ static size_t compress(uint8_t *dst, size_t capacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { - size_t neededBufSize; - neededBufSize = ZSTD_compressBound(size) * 5; - /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); size_t producerSliceSize = FUZZ_dataProducer_uint32Range(producer, 0, size); size = FUZZ_dataProducer_contract(producer, producerSliceSize); + size_t neededBufSize; + neededBufSize = ZSTD_compressBound(size) * 5; + /* Allocate all buffers and contexts if not already allocated */ if (neededBufSize > bufSize) { free(cBuf); diff --git a/tests/fuzz/zstd_frame_info.c b/tests/fuzz/zstd_frame_info.c index 7512d5f49..359cf128f 100644 --- a/tests/fuzz/zstd_frame_info.c +++ b/tests/fuzz/zstd_frame_info.c @@ -21,10 +21,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { ZSTD_frameHeader zfh; - /* Consume the seed to be compatible with the corpora of other decompression - * fuzzers. - */ - FUZZ_seed(&src, &size); /* You can fuzz any helper functions here that are fast, and take zstd * compressed data as input. E.g. don't expect the input to be a dictionary, * so don't fuzz ZSTD_getDictID_fromDict().