/src/lz4/ossfuzz/decompress_frame_fuzzer.c
Line | Count | Source |
1 | | /** |
2 | | * This fuzz target attempts to decompress the fuzzed data with the simple |
3 | | * decompression function to ensure the decompressor never crashes. |
4 | | */ |
5 | | |
6 | | #include <stddef.h> |
7 | | #include <stdint.h> |
8 | | #include <stdlib.h> |
9 | | #include <string.h> |
10 | | |
11 | | #include "fuzz_helpers.h" |
12 | | #include "fuzz_data_producer.h" |
13 | | #include "lz4.h" |
14 | | #define LZ4F_STATIC_LINKING_ONLY |
15 | | #include "lz4frame.h" |
16 | | #include "lz4_helpers.h" |
17 | | |
18 | | static void decompress(LZ4F_dctx* dctx, void* dst, size_t dstCapacity, |
19 | | const void* src, size_t srcSize, |
20 | | const void* dict, size_t dictSize, |
21 | | const LZ4F_decompressOptions_t* opts) |
22 | 9.69k | { |
23 | 9.69k | LZ4F_resetDecompressionContext(dctx); |
24 | 9.69k | if (dictSize == 0) |
25 | 6.15k | LZ4F_decompress(dctx, dst, &dstCapacity, src, &srcSize, opts); |
26 | 3.54k | else |
27 | 3.54k | LZ4F_decompress_usingDict(dctx, dst, &dstCapacity, src, &srcSize, |
28 | 3.54k | dict, dictSize, opts); |
29 | 9.69k | } |
30 | | |
31 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
32 | 2.42k | { |
33 | 2.42k | FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); |
34 | 2.42k | size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); |
35 | 2.42k | size_t const dictSizeSeed = FUZZ_dataProducer_retrieve32(producer); |
36 | 2.42k | size = FUZZ_dataProducer_remainingBytes(producer); |
37 | | |
38 | 2.42k | size_t const dstCapacity = FUZZ_getRange_from_uint32( |
39 | 2.42k | dstCapacitySeed, 0, 4 * size); |
40 | 2.42k | size_t const largeDictSize = 64 * 1024; |
41 | 2.42k | size_t const dictSize = FUZZ_getRange_from_uint32( |
42 | 2.42k | dictSizeSeed, 0, largeDictSize); |
43 | | |
44 | 2.42k | char* const dst = (char*)malloc(dstCapacity); |
45 | 2.42k | char* const dict = (char*)malloc(dictSize); |
46 | 2.42k | LZ4F_decompressOptions_t opts; |
47 | 2.42k | LZ4F_dctx* dctx; |
48 | 2.42k | LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION); |
49 | | |
50 | 2.42k | FUZZ_ASSERT(dctx); |
51 | 2.42k | FUZZ_ASSERT(dst); |
52 | 2.42k | FUZZ_ASSERT(dict); |
53 | | |
54 | | /* Prepare the dictionary. The data doesn't matter for decompression. */ |
55 | 2.42k | memset(dict, 0, dictSize); |
56 | | |
57 | | |
58 | | /* Decompress using multiple configurations. */ |
59 | 2.42k | memset(&opts, 0, sizeof(opts)); |
60 | 2.42k | opts.stableDst = 0; |
61 | 2.42k | decompress(dctx, dst, dstCapacity, data, size, NULL, 0, &opts); |
62 | 2.42k | opts.stableDst = 1; |
63 | 2.42k | decompress(dctx, dst, dstCapacity, data, size, NULL, 0, &opts); |
64 | 2.42k | opts.stableDst = 0; |
65 | 2.42k | decompress(dctx, dst, dstCapacity, data, size, dict, dictSize, &opts); |
66 | 2.42k | opts.stableDst = 1; |
67 | 2.42k | decompress(dctx, dst, dstCapacity, data, size, dict, dictSize, &opts); |
68 | | |
69 | 2.42k | LZ4F_freeDecompressionContext(dctx); |
70 | 2.42k | free(dst); |
71 | 2.42k | free(dict); |
72 | 2.42k | FUZZ_dataProducer_free(producer); |
73 | | |
74 | 2.42k | return 0; |
75 | 2.42k | } |