* Fuzz targets have some common parameters passed as macros during compilation.
* Check the documentation for each individual fuzzer for more parameters.
*
- * @param STATEFULL_FUZZING:
+ * @param STATEFUL_FUZZING:
* Define this to reuse state between fuzzer runs. This can be useful to
* test code paths which are only executed when contexts are reused.
* WARNING: Makes reproducing crashes much harder.
* Default: Not defined.
* @param FUZZ_RNG_SEED_SIZE:
* The number of bytes of the source to look at when constructing a seed
- * for the deterministic RNG.
- * Default: 128.
+ * for the deterministic RNG. These bytes are discarded before passing
+ * the data to zstd functions. Every fuzzer initializes the RNG exactly
+ * once before doing anything else, even if it is unused.
+ * Default: 4.
* @param ZSTD_DEBUG:
* This is a parameter for the zstd library. Defining `ZSTD_DEBUG=1`
* enables assert() statements in the zstd library. Higher levels enable
#define FUZZ_H
#ifndef FUZZ_RNG_SEED_SIZE
-# define FUZZ_RNG_SEED_SIZE 128
+# define FUZZ_RNG_SEED_SIZE 4
#endif
#include <stddef.h>
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size);
+#ifdef __cplusplus
+}
+#endif
+
#endif
#include <stdint.h>
#include <stdio.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/**
* Determininistically constructs a seed based on the fuzz input.
- * Only looks at the first FUZZ_RNG_SEED_SIZE bytes of the input.
+ * Consumes up to the first FUZZ_RNG_SEED_SIZE bytes of the input.
*/
-FUZZ_STATIC uint32_t FUZZ_seed(const uint8_t *src, size_t size) {
- size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, size);
- return XXH32(src, toHash, 0);
+FUZZ_STATIC uint32_t FUZZ_seed(uint8_t const **src, size_t* size) {
+ size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, *size);
+ return XXH32(*src, toHash, 0);
+ *size -= toHash;
+ *src += toHash;
}
#define FUZZ_rotl32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
return rand32 >> 5;
}
+#ifdef __cplusplus
+}
+#endif
+
#endif
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
- size_t const neededBufSize = MAX(20 * size, (size_t)256 << 10);
+ size_t neededBufSize;
+
+ FUZZ_seed(&src, &size);
+ neededBufSize = MAX(20 * size, (size_t)256 << 10);
/* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) {
}
ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, src, size);
-#ifndef STATEFULL_FUZZING
+#ifndef STATEFUL_FUZZING
ZSTD_freeDCtx(dctx); dctx = NULL;
#endif
return 0;
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
- size_t const neededBufSize = ZSTD_compressBound(size);
+ size_t neededBufSize;
- seed = FUZZ_seed(src, size);
+ seed = FUZZ_seed(&src, &size);
+ neededBufSize = ZSTD_compressBound(size);
/* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) {
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
}
-#ifndef STATEFULL_FUZZING
+#ifndef STATEFUL_FUZZING
ZSTD_freeCCtx(cctx); cctx = NULL;
ZSTD_freeDCtx(dctx); dctx = NULL;
#endif
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
- seed = FUZZ_seed(src, size);
+ seed = FUZZ_seed(&src, &size);
/* Allocate all buffers and contexts if not already allocated */
if (!buf) {
}
error:
-#ifndef STATEFULL_FUZZING
+#ifndef STATEFUL_FUZZING
ZSTD_freeDStream(dstream); dstream = NULL;
#endif
return 0;
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
- size_t const neededBufSize = ZSTD_compressBound(size) * 2;
+ size_t neededBufSize;
- seed = FUZZ_seed(src, size);
+ seed = FUZZ_seed(&src, &size);
+ neededBufSize = ZSTD_compressBound(size) * 2;
/* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) {
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
}
-#ifndef STATEFULL_FUZZING
+#ifndef STATEFUL_FUZZING
ZSTD_freeCStream(cstream); cstream = NULL;
ZSTD_freeDCtx(dctx); dctx = NULL;
#endif