git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / dictionary_loader.c
CommitLineData
648db22b 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 */
28static 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
48static 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
69int 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
100out:
101 free(cBuf);
102 free(rBuf);
103 FUZZ_dataProducer_free(producer);
104 FUZZ_SEQ_PROD_TEARDOWN();
105 return 0;
106}