git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / block_round_trip.c
1 /**
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
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).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10
11 /**
12  * This fuzz target performs a zstd round-trip test (compress & decompress),
13  * compares the result with the original, and calls abort() on corruption.
14  */
15
16 #define ZSTD_STATIC_LINKING_ONLY
17
18 #include <stddef.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include "fuzz_helpers.h"
23 #include "zstd.h"
24 #include "zstd_helpers.h"
25 #include "fuzz_data_producer.h"
26 #include "fuzz_third_party_seq_prod.h"
27
28 static ZSTD_CCtx *cctx = NULL;
29 static ZSTD_DCtx *dctx = NULL;
30 static void* cBuf = NULL;
31 static void* rBuf = NULL;
32 static size_t bufSize = 0;
33
34 static size_t roundTripTest(void *result, size_t resultCapacity,
35                             void *compressed, size_t compressedCapacity,
36                             const void *src, size_t srcSize,
37                             int cLevel)
38 {
39     ZSTD_parameters const params = ZSTD_getParams(cLevel, srcSize, 0);
40     size_t ret = ZSTD_compressBegin_advanced(cctx, NULL, 0, params, srcSize);
41     FUZZ_ZASSERT(ret);
42
43     ret = ZSTD_compressBlock(cctx, compressed, compressedCapacity, src, srcSize);
44     FUZZ_ZASSERT(ret);
45     if (ret == 0) {
46         FUZZ_ASSERT(resultCapacity >= srcSize);
47         if (srcSize > 0) {
48             memcpy(result, src, srcSize);
49         }
50         return srcSize;
51     }
52     ZSTD_decompressBegin(dctx);
53     return ZSTD_decompressBlock(dctx, result, resultCapacity, compressed, ret);
54 }
55
56 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
57 {
58     FUZZ_SEQ_PROD_SETUP();
59
60     /* Give a random portion of src data to the producer, to use for
61     parameter generation. The rest will be used for (de)compression */
62     FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
63     size = FUZZ_dataProducer_reserveDataPrefix(producer);
64
65     int const cLevel = FUZZ_dataProducer_int32Range(producer, kMinClevel, kMaxClevel);
66
67     size_t neededBufSize = size;
68     if (size > ZSTD_BLOCKSIZE_MAX)
69         size = ZSTD_BLOCKSIZE_MAX;
70
71     /* Allocate all buffers and contexts if not already allocated */
72     if (neededBufSize > bufSize || !cBuf || !rBuf) {
73         free(cBuf);
74         free(rBuf);
75         cBuf = FUZZ_malloc(neededBufSize);
76         rBuf = FUZZ_malloc(neededBufSize);
77         bufSize = neededBufSize;
78     }
79     if (!cctx) {
80         cctx = ZSTD_createCCtx();
81         FUZZ_ASSERT(cctx);
82     }
83     if (!dctx) {
84         dctx = ZSTD_createDCtx();
85         FUZZ_ASSERT(dctx);
86     }
87
88     {
89         size_t const result =
90             roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size,
91               cLevel);
92         FUZZ_ZASSERT(result);
93         FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
94         FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
95     }
96     FUZZ_dataProducer_free(producer);
97 #ifndef STATEFUL_FUZZING
98     ZSTD_freeCCtx(cctx); cctx = NULL;
99     ZSTD_freeDCtx(dctx); dctx = NULL;
100 #endif
101     FUZZ_SEQ_PROD_TEARDOWN();
102     return 0;
103 }