/src/zstd/tests/fuzz/generate_sequences.c
Line | Count | Source |
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 | | #define ZSTD_STATIC_LINKING_ONLY |
12 | | |
13 | | #include <stddef.h> |
14 | | #include <stdint.h> |
15 | | #include <string.h> |
16 | | #include <stdlib.h> |
17 | | |
18 | | #include "fuzz_data_producer.h" |
19 | | #include "fuzz_helpers.h" |
20 | | #include "zstd_helpers.h" |
21 | | |
22 | | /** |
23 | | * This fuzz target ensures that ZSTD_generateSequences() does not crash and |
24 | | * if it succeeds that ZSTD_compressSequences() round trips. |
25 | | */ |
26 | | |
27 | 44.8k | static void testRoundTrip(ZSTD_CCtx* cctx, ZSTD_Sequence const* seqs, size_t nbSeqs, const void* src, size_t srcSize) { |
28 | | /* Compress the sequences with block delimiters */ |
29 | 44.8k | const size_t compressBound = ZSTD_compressBound(srcSize); |
30 | 44.8k | void* dst = FUZZ_malloc(compressBound); |
31 | 44.8k | FUZZ_ASSERT(dst); |
32 | | |
33 | 44.8k | size_t compressedSize = ZSTD_compressSequences(cctx, dst, compressBound, seqs, nbSeqs, src, srcSize); |
34 | 44.8k | FUZZ_ZASSERT(compressedSize); |
35 | | |
36 | 44.8k | void* decompressed = FUZZ_malloc(srcSize); |
37 | 44.8k | FUZZ_ASSERT(srcSize == 0 || decompressed); |
38 | 44.8k | size_t decompressedSize = ZSTD_decompress(decompressed, srcSize, dst, compressedSize); |
39 | 44.8k | FUZZ_ZASSERT(decompressedSize); |
40 | 44.8k | FUZZ_ASSERT(decompressedSize == srcSize); |
41 | 44.8k | if (srcSize != 0) { |
42 | 44.5k | FUZZ_ASSERT(!memcmp(src, decompressed, srcSize)); |
43 | 44.5k | } |
44 | | |
45 | 44.8k | free(decompressed); |
46 | 44.8k | free(dst); |
47 | 44.8k | } |
48 | | |
49 | 27.4k | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
50 | | |
51 | 27.4k | FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); |
52 | 27.4k | size = FUZZ_dataProducer_reserveDataPrefix(producer); |
53 | | |
54 | 27.4k | ZSTD_CCtx* cctx = ZSTD_createCCtx(); |
55 | 27.4k | FUZZ_ASSERT(cctx); |
56 | | |
57 | 27.4k | const size_t seqsCapacity = FUZZ_dataProducer_uint32Range(producer, 0, 2 * ZSTD_sequenceBound(size)); |
58 | 27.4k | ZSTD_Sequence* seqs = (ZSTD_Sequence*)FUZZ_malloc(sizeof(ZSTD_Sequence) * seqsCapacity); |
59 | 27.4k | FUZZ_ASSERT(seqsCapacity == 0 || seqs); |
60 | | |
61 | 27.4k | FUZZ_setRandomParameters(cctx, size, producer); |
62 | 27.4k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetCBlockSize, 0)); |
63 | 27.4k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 0)); |
64 | | |
65 | 27.4k | const size_t nbSeqs = ZSTD_generateSequences(cctx, seqs, seqsCapacity, data, size); |
66 | 27.4k | if (ZSTD_isError(nbSeqs)) { |
67 | | /* Allowed to error if the destination is too small */ |
68 | 5.00k | if (ZSTD_getErrorCode(nbSeqs) == ZSTD_error_dstSize_tooSmall) { |
69 | 4.82k | FUZZ_ASSERT(seqsCapacity < ZSTD_sequenceBound(size)); |
70 | 4.82k | } |
71 | 22.4k | } else { |
72 | | /* Ensure we round trip with and without block delimiters*/ |
73 | | |
74 | 22.4k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters)); |
75 | 22.4k | testRoundTrip(cctx, seqs, nbSeqs, data, size); |
76 | | |
77 | 22.4k | const size_t nbMergedSeqs = ZSTD_mergeBlockDelimiters(seqs, nbSeqs); |
78 | 22.4k | FUZZ_ASSERT(nbMergedSeqs <= nbSeqs); |
79 | 22.4k | FUZZ_ZASSERT(ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only)); |
80 | 22.4k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_noBlockDelimiters)); |
81 | 22.4k | testRoundTrip(cctx, seqs, nbMergedSeqs, data, size); |
82 | 22.4k | } |
83 | | |
84 | 27.4k | free(seqs); |
85 | 27.4k | ZSTD_freeCCtx(cctx); |
86 | 27.4k | FUZZ_dataProducer_free(producer); |
87 | 27.4k | return 0; |
88 | 27.4k | } |