]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/zstd/tests/fuzz/simple_round_trip.c
Import zstandard 1.3.1
[FreeBSD/FreeBSD.git] / contrib / zstd / tests / fuzz / simple_round_trip.c
1 /**
2  * Copyright (c) 2016-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  */
9
10 /**
11  * This fuzz target performs a zstd round-trip test (compress & decompress),
12  * compares the result with the original, and calls abort() on corruption.
13  */
14
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include "fuzz_helpers.h"
20 #include "zstd.h"
21
22 static const int kMaxClevel = 19;
23
24 static ZSTD_CCtx *cctx = NULL;
25 static ZSTD_DCtx *dctx = NULL;
26 static void* cBuf = NULL;
27 static void* rBuf = NULL;
28 static size_t bufSize = 0;
29 static uint32_t seed;
30
31 static size_t roundTripTest(void *result, size_t resultCapacity,
32                             void *compressed, size_t compressedCapacity,
33                             const void *src, size_t srcSize)
34 {
35   int const cLevel = FUZZ_rand(&seed) % kMaxClevel;
36   size_t const cSize = ZSTD_compressCCtx(cctx, compressed, compressedCapacity,
37                                          src, srcSize, cLevel);
38   if (ZSTD_isError(cSize)) {
39     fprintf(stderr, "Compression error: %s\n", ZSTD_getErrorName(cSize));
40     return cSize;
41   }
42   return ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize);
43 }
44
45 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
46 {
47     size_t const neededBufSize = ZSTD_compressBound(size);
48
49     seed = FUZZ_seed(src, size);
50
51     /* Allocate all buffers and contexts if not already allocated */
52     if (neededBufSize > bufSize) {
53         free(cBuf);
54         free(rBuf);
55         cBuf = malloc(neededBufSize);
56         rBuf = malloc(neededBufSize);
57         bufSize = neededBufSize;
58         FUZZ_ASSERT(cBuf && rBuf);
59     }
60     if (!cctx) {
61         cctx = ZSTD_createCCtx();
62         FUZZ_ASSERT(cctx);
63     }
64     if (!dctx) {
65         dctx = ZSTD_createDCtx();
66         FUZZ_ASSERT(dctx);
67     }
68
69     {
70         size_t const result =
71             roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size);
72         FUZZ_ASSERT_MSG(!ZSTD_isError(result), ZSTD_getErrorName(result));
73         FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
74         FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
75     }
76 #ifndef STATEFULL_FUZZING
77     ZSTD_freeCCtx(cctx); cctx = NULL;
78     ZSTD_freeDCtx(dctx); dctx = NULL;
79 #endif
80     return 0;
81 }