2 * Copyright (c) 2016-present, Facebook, Inc.
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
11 * This fuzz target performs a zstd round-trip test (compress & decompress),
12 * compares the result with the original, and calls abort() on corruption.
15 #define ZSTD_STATIC_LINKING_ONLY
21 #include "fuzz_helpers.h"
22 #include "zstd_helpers.h"
23 #include "fuzz_data_producer.h"
25 static ZSTD_CCtx *cctx = NULL;
26 static ZSTD_DCtx *dctx = NULL;
28 static size_t roundTripTest(void *result, size_t resultCapacity,
29 void *compressed, size_t compressedCapacity,
30 const void *src, size_t srcSize,
31 FUZZ_dataProducer_t *producer)
34 if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) {
35 FUZZ_setRandomParameters(cctx, srcSize, producer);
36 cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize);
38 int const cLevel = FUZZ_dataProducer_int32Range(producer, kMinClevel, kMaxClevel);
40 cSize = ZSTD_compressCCtx(
41 cctx, compressed, compressedCapacity, src, srcSize, cLevel);
44 return ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize);
47 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
49 size_t const rBufSize = size;
50 void* rBuf = malloc(rBufSize);
51 size_t cBufSize = ZSTD_compressBound(size);
54 /* Give a random portion of src data to the producer, to use for
55 parameter generation. The rest will be used for (de)compression */
56 FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
57 size = FUZZ_dataProducer_reserveDataPrefix(producer);
59 /* Half of the time fuzz with a 1 byte smaller output size.
60 * This will still succeed because we don't use a dictionary, so the dictID
61 * field is empty, giving us 4 bytes of overhead.
63 cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
65 cBuf = malloc(cBufSize);
67 FUZZ_ASSERT(cBuf && rBuf);
70 cctx = ZSTD_createCCtx();
74 dctx = ZSTD_createDCtx();
80 roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
82 FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
83 FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
87 FUZZ_dataProducer_free(producer);
88 #ifndef STATEFUL_FUZZING
89 ZSTD_freeCCtx(cctx); cctx = NULL;
90 ZSTD_freeDCtx(dctx); dctx = NULL;