xref: /aosp_15_r20/external/brotli/c/fuzz/decode_fuzzer.c (revision f4ee7fba7774faf2a30f13154332c0a06550dbc4)
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