1 #include <fuzzer/FuzzedDataProvider.h>
2 
3 #include <cstddef>
4 #include <cstdint>
5 #include <cstdio>
6 #include <cstdlib>
7 #include <vector>
8 
9 #include "mpg123.h"
10 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)11 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
12   static bool initialized = false;
13   if (!initialized) {
14     mpg123_init();
15     initialized = true;
16   }
17   int ret;
18   mpg123_handle* handle = mpg123_new(nullptr, &ret);
19   if (handle == nullptr) {
20     return 0;
21   }
22 
23   ret = mpg123_param(handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.);
24   if(ret == MPG123_OK)
25     ret = mpg123_open_feed(handle);
26   if (ret != MPG123_OK) {
27     mpg123_delete(handle);
28     return 0;
29   }
30 
31   std::vector<uint8_t> output_buffer(mpg123_outblock(handle));
32 
33   size_t output_written = 0;
34   // Initially, start by feeding the decoder more data.
35   int decode_ret = MPG123_NEED_MORE;
36   FuzzedDataProvider provider(data, size);
37   while ((decode_ret != MPG123_ERR)) {
38     if (decode_ret == MPG123_NEED_MORE) {
39       if (provider.remaining_bytes() == 0
40           || mpg123_tellframe(handle) > 10000
41           || mpg123_tell_stream(handle) > 1<<20) {
42         break;
43       }
44       const size_t next_size = provider.ConsumeIntegralInRange<size_t>(
45           0,
46           provider.remaining_bytes());
47       auto next_input = provider.ConsumeBytes<unsigned char>(next_size);
48       decode_ret = mpg123_decode(handle, next_input.data(), next_input.size(),
49                                  output_buffer.data(), output_buffer.size(),
50                                  &output_written);
51     } else if (decode_ret != MPG123_ERR && decode_ret != MPG123_NEED_MORE) {
52       decode_ret = mpg123_decode(handle, nullptr, 0, output_buffer.data(),
53                                  output_buffer.size(), &output_written);
54     } else {
55       // Unhandled mpg123_decode return value.
56       abort();
57     }
58   }
59 
60   mpg123_delete(handle);
61 
62   return 0;
63 }
64