git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / tests / fuzz / seekable_roundtrip.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#include "zstd.h"
12#include "zstd_seekable.h"
13#include "fuzz_helpers.h"
14#include "fuzz_data_producer.h"
15
16static ZSTD_seekable *stream = NULL;
17static ZSTD_seekable_CStream *zscs = NULL;
18static const size_t kSeekableOverheadSize = ZSTD_seekTableFooterSize;
19
20int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
21{
22 /* Give a random portion of src data to the producer, to use for
23 parameter generation. The rest will be used for (de)compression */
24 FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
25 size = FUZZ_dataProducer_reserveDataPrefix(producer);
26 size_t const compressedBufferSize = ZSTD_compressBound(size) + kSeekableOverheadSize;
27 uint8_t* compressedBuffer = (uint8_t*)malloc(compressedBufferSize);
28 uint8_t* decompressedBuffer = (uint8_t*)malloc(size);
29
30 int const cLevel = FUZZ_dataProducer_int32Range(producer, ZSTD_minCLevel(), ZSTD_maxCLevel());
31 unsigned const checksumFlag = FUZZ_dataProducer_int32Range(producer, 0, 1);
32 size_t const uncompressedSize = FUZZ_dataProducer_uint32Range(producer, 0, size);
33 size_t const offset = FUZZ_dataProducer_uint32Range(producer, 0, size - uncompressedSize);
34 size_t seekSize;
35
36 if (!zscs) {
37 zscs = ZSTD_seekable_createCStream();
38 FUZZ_ASSERT(zscs);
39 }
40 if (!stream) {
41 stream = ZSTD_seekable_create();
42 FUZZ_ASSERT(stream);
43 }
44
45 { /* Perform a compression */
46 size_t const initStatus = ZSTD_seekable_initCStream(zscs, cLevel, checksumFlag, size);
47 size_t endStatus;
48 ZSTD_outBuffer out = { .dst=compressedBuffer, .pos=0, .size=compressedBufferSize };
49 ZSTD_inBuffer in = { .src=src, .pos=0, .size=size };
50 FUZZ_ASSERT(!ZSTD_isError(initStatus));
51
52 do {
53 size_t cSize = ZSTD_seekable_compressStream(zscs, &out, &in);
54 FUZZ_ASSERT(!ZSTD_isError(cSize));
55 } while (in.pos != in.size);
56
57 FUZZ_ASSERT(in.pos == in.size);
58 endStatus = ZSTD_seekable_endStream(zscs, &out);
59 FUZZ_ASSERT(!ZSTD_isError(endStatus));
60 seekSize = out.pos;
61 }
62
63 { /* Decompress at an offset */
64 size_t const initStatus = ZSTD_seekable_initBuff(stream, compressedBuffer, seekSize);
65 size_t decompressedBytesTotal = 0;
66 size_t dSize;
67
68 FUZZ_ZASSERT(initStatus);
69 do {
70 dSize = ZSTD_seekable_decompress(stream, decompressedBuffer, uncompressedSize, offset);
71 FUZZ_ASSERT(!ZSTD_isError(dSize));
72 decompressedBytesTotal += dSize;
73 } while (decompressedBytesTotal < uncompressedSize && dSize > 0);
74 FUZZ_ASSERT(decompressedBytesTotal == uncompressedSize);
75 }
76
77 FUZZ_ASSERT_MSG(!FUZZ_memcmp(src+offset, decompressedBuffer, uncompressedSize), "Corruption!");
78
79 free(decompressedBuffer);
80 free(compressedBuffer);
81 FUZZ_dataProducer_free(producer);
82
83#ifndef STATEFUL_FUZZING
84 ZSTD_seekable_free(stream); stream = NULL;
85 ZSTD_seekable_freeCStream(zscs); zscs = NULL;
86#endif
87 return 0;
88}