/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 | 48.3k | 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 | 48.3k | const size_t compressBound = ZSTD_compressBound(srcSize); |
30 | 48.3k | void* dst = FUZZ_malloc(compressBound); |
31 | 48.3k | FUZZ_ASSERT(dst); |
32 | | |
33 | 48.3k | size_t compressedSize = ZSTD_compressSequences(cctx, dst, compressBound, seqs, nbSeqs, src, srcSize); |
34 | 48.3k | FUZZ_ZASSERT(compressedSize); |
35 | | |
36 | 48.3k | void* decompressed = FUZZ_malloc(srcSize); |
37 | 48.3k | FUZZ_ASSERT(srcSize == 0 || decompressed); |
38 | 48.3k | size_t decompressedSize = ZSTD_decompress(decompressed, srcSize, dst, compressedSize); |
39 | 48.3k | FUZZ_ZASSERT(decompressedSize); |
40 | 48.3k | FUZZ_ASSERT(decompressedSize == srcSize); |
41 | 48.3k | if (srcSize != 0) { |
42 | 48.1k | FUZZ_ASSERT(!memcmp(src, decompressed, srcSize)); |
43 | 48.1k | } |
44 | | |
45 | 48.3k | free(decompressed); |
46 | 48.3k | free(dst); |
47 | 48.3k | } |
48 | | |
49 | 30.0k | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
50 | | |
51 | 30.0k | FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); |
52 | 30.0k | size = FUZZ_dataProducer_reserveDataPrefix(producer); |
53 | | |
54 | 30.0k | ZSTD_CCtx* cctx = ZSTD_createCCtx(); |
55 | 30.0k | FUZZ_ASSERT(cctx); |
56 | | |
57 | 30.0k | const size_t seqsCapacity = FUZZ_dataProducer_uint32Range(producer, 0, 2 * ZSTD_sequenceBound(size)); |
58 | 30.0k | ZSTD_Sequence* seqs = (ZSTD_Sequence*)FUZZ_malloc(sizeof(ZSTD_Sequence) * seqsCapacity); |
59 | 30.0k | FUZZ_ASSERT(seqsCapacity == 0 || seqs); |
60 | | |
61 | 30.0k | FUZZ_setRandomParameters(cctx, size, producer); |
62 | 30.0k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetCBlockSize, 0)); |
63 | 30.0k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 0)); |
64 | | |
65 | 30.0k | const size_t nbSeqs = ZSTD_generateSequences(cctx, seqs, seqsCapacity, data, size); |
66 | 30.0k | if (ZSTD_isError(nbSeqs)) { |
67 | | /* Allowed to error if the destination is too small */ |
68 | 5.83k | if (ZSTD_getErrorCode(nbSeqs) == ZSTD_error_dstSize_tooSmall) { |
69 | 5.59k | FUZZ_ASSERT(seqsCapacity < ZSTD_sequenceBound(size)); |
70 | 5.59k | } |
71 | 24.1k | } else { |
72 | | /* Ensure we round trip with and without block delimiters*/ |
73 | | |
74 | 24.1k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters)); |
75 | 24.1k | testRoundTrip(cctx, seqs, nbSeqs, data, size); |
76 | | |
77 | 24.1k | const size_t nbMergedSeqs = ZSTD_mergeBlockDelimiters(seqs, nbSeqs); |
78 | 24.1k | FUZZ_ASSERT(nbMergedSeqs <= nbSeqs); |
79 | 24.1k | FUZZ_ZASSERT(ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only)); |
80 | 24.1k | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_noBlockDelimiters)); |
81 | 24.1k | testRoundTrip(cctx, seqs, nbMergedSeqs, data, size); |
82 | 24.1k | } |
83 | | |
84 | 30.0k | free(seqs); |
85 | 30.0k | ZSTD_freeCCtx(cctx); |
86 | 30.0k | FUZZ_dataProducer_free(producer); |
87 | 30.0k | return 0; |
88 | 30.0k | } |