/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 | 2.70k | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
13 | 2.70k | size_t addend = 0; |
14 | 2.70k | if (size > 0) |
15 | 2.70k | addend = data[size - 1] & 7; |
16 | 2.70k | const uint8_t* next_in = data; |
17 | | |
18 | 2.70k | const int kBufferSize = 1024; |
19 | 2.70k | uint8_t* buffer = (uint8_t*) malloc(kBufferSize); |
20 | 2.70k | 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 | 2.70k | const size_t total_out_limit = (addend == 0) ? (1 << 26) : (1 << 24); |
27 | 2.70k | size_t total_out = 0; |
28 | | |
29 | 2.70k | BrotliDecoderState* state = BrotliDecoderCreateInstance(0, 0, 0); |
30 | 2.70k | if (!state) { |
31 | | // OOM is out-of-scope here. |
32 | 0 | free(buffer); |
33 | 0 | return 0; |
34 | 0 | } |
35 | | |
36 | 2.70k | if (addend == 0) |
37 | 1.20k | addend = size; |
38 | | /* Test both fast (addend == size) and slow (addend <= 7) decoding paths. */ |
39 | 2.42M | for (size_t i = 0; i < size;) { |
40 | 2.42M | size_t next_i = i + addend; |
41 | 2.42M | if (next_i > size) |
42 | 578 | next_i = size; |
43 | 2.42M | size_t avail_in = next_i - i; |
44 | 2.42M | i = next_i; |
45 | 2.42M | BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; |
46 | 6.97M | while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { |
47 | 4.54M | size_t avail_out = kBufferSize; |
48 | 4.54M | uint8_t* next_out = buffer; |
49 | 4.54M | result = BrotliDecoderDecompressStream( |
50 | 4.54M | state, &avail_in, &next_in, &avail_out, &next_out, &total_out); |
51 | 4.54M | if (total_out > total_out_limit) |
52 | 9 | break; |
53 | 4.54M | } |
54 | 2.42M | if (total_out > total_out_limit) |
55 | 9 | break; |
56 | 2.42M | if (result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) |
57 | 898 | break; |
58 | 2.42M | } |
59 | | |
60 | 2.70k | BrotliDecoderDestroyInstance(state); |
61 | 2.70k | free(buffer); |
62 | 2.70k | return 0; |
63 | 2.70k | } |