git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / raw_dictionary_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) with
13  * a raw content dictionary, compares the result with the original, and calls
14  * abort() on corruption.
15  */
16
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include "fuzz_helpers.h"
22 #include "zstd_helpers.h"
23 #include "fuzz_data_producer.h"
24 #include "fuzz_third_party_seq_prod.h"
25
26 static ZSTD_CCtx *cctx = NULL;
27 static ZSTD_DCtx *dctx = NULL;
28
29 static size_t roundTripTest(void *result, size_t resultCapacity,
30                             void *compressed, size_t compressedCapacity,
31                             const void *src, size_t srcSize,
32                             const void *dict, size_t dictSize,
33                             FUZZ_dataProducer_t *producer)
34 {
35     ZSTD_dictContentType_e const dictContentType = ZSTD_dct_rawContent;
36     int const refPrefix = FUZZ_dataProducer_uint32Range(producer, 0, 1) != 0;
37     size_t cSize;
38
39     FUZZ_setRandomParameters(cctx, srcSize, producer);
40     /* Disable checksum so we can use sizes smaller than compress bound. */
41     FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0));
42     if (refPrefix)
43         FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced(
44             cctx, dict, dictSize,
45             ZSTD_dct_rawContent));
46     else
47         FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced(
48             cctx, dict, dictSize,
49             (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1),
50             ZSTD_dct_rawContent));
51     cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize);
52     FUZZ_ZASSERT(cSize);
53
54     if (refPrefix)
55         FUZZ_ZASSERT(ZSTD_DCtx_refPrefix_advanced(
56             dctx, dict, dictSize,
57             dictContentType));
58     else
59         FUZZ_ZASSERT(ZSTD_DCtx_loadDictionary_advanced(
60             dctx, dict, dictSize,
61             (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1),
62             dictContentType));
63     {
64         size_t const ret = ZSTD_decompressDCtx(
65                 dctx, result, resultCapacity, compressed, cSize);
66         return ret;
67     }
68 }
69
70 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
71 {
72     FUZZ_SEQ_PROD_SETUP();
73
74     /* Give a random portion of src data to the producer, to use for
75     parameter generation. The rest will be used for (de)compression */
76     FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
77     size = FUZZ_dataProducer_reserveDataPrefix(producer);
78
79     uint8_t const* const srcBuf = src;
80     size_t const srcSize = FUZZ_dataProducer_uint32Range(producer, 0, size);
81     uint8_t const* const dictBuf = srcBuf + srcSize;
82     size_t const dictSize = size - srcSize;
83     size_t const decompSize = srcSize;
84     void* const decompBuf = FUZZ_malloc(decompSize);
85     size_t compSize = ZSTD_compressBound(srcSize);
86     void* compBuf;
87     /* Half of the time fuzz with a 1 byte smaller output size.
88      * This will still succeed because we force the checksum to be disabled,
89      * giving us 4 bytes of overhead.
90      */
91     compSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
92     compBuf = FUZZ_malloc(compSize);
93
94     if (!cctx) {
95         cctx = ZSTD_createCCtx();
96         FUZZ_ASSERT(cctx);
97     }
98     if (!dctx) {
99         dctx = ZSTD_createDCtx();
100         FUZZ_ASSERT(dctx);
101     }
102
103     {
104         size_t const result =
105             roundTripTest(decompBuf, decompSize, compBuf, compSize, srcBuf, srcSize, dictBuf, dictSize, producer);
106         FUZZ_ZASSERT(result);
107         FUZZ_ASSERT_MSG(result == srcSize, "Incorrect regenerated size");
108         FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, decompBuf, srcSize), "Corruption!");
109     }
110     free(decompBuf);
111     free(compBuf);
112     FUZZ_dataProducer_free(producer);
113 #ifndef STATEFUL_FUZZING
114     ZSTD_freeCCtx(cctx); cctx = NULL;
115     ZSTD_freeDCtx(dctx); dctx = NULL;
116 #endif
117     FUZZ_SEQ_PROD_TEARDOWN();
118     return 0;
119 }