/src/brotli/c/fuzz/decode_fuzzer.c
Line | Count | Source |
1 | | // Copyright 2015 The Chromium Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #include <stddef.h> |
6 | | #include <stdint.h> |
7 | | #include <stdlib.h> |
8 | | |
9 | | #include <brotli/decode.h> |
10 | | |
11 | | // Entry point for LibFuzzer. |
12 | 4.82k | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
13 | 4.82k | size_t addend = 0; |
14 | 4.82k | if (size > 0) |
15 | 4.82k | addend = data[size - 1] & 7; |
16 | 4.82k | const uint8_t* next_in = data; |
17 | | |
18 | 4.82k | const int kBufferSize = 1024; |
19 | 4.82k | uint8_t* buffer = (uint8_t*) malloc(kBufferSize); |
20 | 4.82k | if (!buffer) { |
21 | | // OOM is out-of-scope here. |
22 | 0 | return 0; |
23 | 0 | } |
24 | | /* The biggest "magic number" in brotli is 16MiB - 16, so no need to check |
25 | | the cases with much longer output. */ |
26 | 4.82k | const size_t total_out_limit = (addend == 0) ? (1 << 26) : (1 << 24); |
27 | 4.82k | size_t total_out = 0; |
28 | | |
29 | 4.82k | BrotliDecoderState* state = BrotliDecoderCreateInstance(0, 0, 0); |
30 | 4.82k | if (!state) { |
31 | | // OOM is out-of-scope here. |
32 | 0 | free(buffer); |
33 | 0 | return 0; |
34 | 0 | } |
35 | | |
36 | 4.82k | if (addend == 0) |
37 | 2.17k | addend = size; |
38 | | /* Test both fast (addend == size) and slow (addend <= 7) decoding paths. */ |
39 | 1.21M | for (size_t i = 0; i < size;) { |
40 | 1.21M | size_t next_i = i + addend; |
41 | 1.21M | if (next_i > size) |
42 | 1.07k | next_i = size; |
43 | 1.21M | size_t avail_in = next_i - i; |
44 | 1.21M | i = next_i; |
45 | 1.21M | BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; |
46 | 5.56M | while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { |
47 | 4.35M | size_t avail_out = kBufferSize; |
48 | 4.35M | uint8_t* next_out = buffer; |
49 | 4.35M | result = BrotliDecoderDecompressStream( |
50 | 4.35M | state, &avail_in, &next_in, &avail_out, &next_out, &total_out); |
51 | 4.35M | if (total_out > total_out_limit) |
52 | 12 | break; |
53 | 4.35M | } |
54 | 1.21M | if (total_out > total_out_limit) |
55 | 12 | break; |
56 | 1.21M | if (result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) |
57 | 1.60k | break; |
58 | 1.21M | } |
59 | | |
60 | 4.82k | BrotliDecoderDestroyInstance(state); |
61 | 4.82k | free(buffer); |
62 | 4.82k | return 0; |
63 | 4.82k | } |