7b7c00428a799c777d986874dd521ed7e9d02bfc
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / dictionary_loader.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 makes sure that whenever a compression dictionary can be
13  * loaded, the data can be round tripped.
14  */
15
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include "fuzz_helpers.h"
21 #include "zstd_helpers.h"
22 #include "fuzz_data_producer.h"
23 #include "fuzz_third_party_seq_prod.h"
24
25 /**
26  * Compresses the data and returns the compressed size or an error.
27  */
28 static size_t compress(void* compressed, size_t compressedCapacity,
29                        void const* source, size_t sourceSize,
30                        void const* dict, size_t dictSize,
31                        ZSTD_dictLoadMethod_e dictLoadMethod,
32                        ZSTD_dictContentType_e dictContentType,
33                        int const refPrefix)
34 {
35     ZSTD_CCtx* cctx = ZSTD_createCCtx();
36     if (refPrefix)
37         FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced(
38             cctx, dict, dictSize, dictContentType));
39     else
40         FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced(
41             cctx, dict, dictSize, dictLoadMethod, dictContentType));
42     size_t const compressedSize = ZSTD_compress2(
43             cctx, compressed, compressedCapacity, source, sourceSize);
44     ZSTD_freeCCtx(cctx);
45     return compressedSize;
46 }
47
48 static size_t decompress(void* result, size_t resultCapacity,
49                          void const* compressed, size_t compressedSize,
50                          void const* dict, size_t dictSize,
51                        ZSTD_dictLoadMethod_e dictLoadMethod,
52                          ZSTD_dictContentType_e dictContentType,
53                          int const refPrefix)
54 {
55     ZSTD_DCtx* dctx = ZSTD_createDCtx();
56     if (refPrefix)
57         FUZZ_ZASSERT(ZSTD_DCtx_refPrefix_advanced(
58             dctx, dict, dictSize, dictContentType));
59     else
60         FUZZ_ZASSERT(ZSTD_DCtx_loadDictionary_advanced(
61             dctx, dict, dictSize, dictLoadMethod, dictContentType));
62     size_t const resultSize = ZSTD_decompressDCtx(
63             dctx, result, resultCapacity, compressed, compressedSize);
64     FUZZ_ZASSERT(resultSize);
65     ZSTD_freeDCtx(dctx);
66     return resultSize;
67 }
68
69 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
70 {
71     FUZZ_SEQ_PROD_SETUP();
72     FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
73     int const refPrefix = FUZZ_dataProducer_uint32Range(producer, 0, 1) != 0;
74     ZSTD_dictLoadMethod_e const dlm =
75     size = FUZZ_dataProducer_uint32Range(producer, 0, 1);
76     ZSTD_dictContentType_e const dct =
77             FUZZ_dataProducer_uint32Range(producer, 0, 2);
78     size = FUZZ_dataProducer_remainingBytes(producer);
79
80     DEBUGLOG(2, "Dict load method %d", dlm);
81     DEBUGLOG(2, "Dict content type %d", dct);
82     DEBUGLOG(2, "Dict size %u", (unsigned)size);
83
84     void* const rBuf = FUZZ_malloc(size);
85     size_t const cBufSize = ZSTD_compressBound(size);
86     void* const cBuf = FUZZ_malloc(cBufSize);
87
88     size_t const cSize =
89             compress(cBuf, cBufSize, src, size, src, size, dlm, dct, refPrefix);
90     /* compression failing is okay */
91     if (ZSTD_isError(cSize)) {
92       FUZZ_ASSERT_MSG(dct != ZSTD_dct_rawContent, "Raw must always succeed!");
93       goto out;
94     }
95     size_t const rSize =
96             decompress(rBuf, size, cBuf, cSize, src, size, dlm, dct, refPrefix);
97     FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
98     FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
99
100 out:
101     free(cBuf);
102     free(rBuf);
103     FUZZ_dataProducer_free(producer);
104     FUZZ_SEQ_PROD_TEARDOWN();
105     return 0;
106 }