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