blob: 4fe4b2e638e1d2b5c8dea994076cc7455baa5c19 [file] [log] [blame]
#include <fuzzer/FuzzedDataProvider.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "mpg123.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static bool initialized = false;
if (!initialized) {
mpg123_init();
initialized = true;
}
int ret;
mpg123_handle* handle = mpg123_new(nullptr, &ret);
if (handle == nullptr) {
return 0;
}
ret = mpg123_param(handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.);
if(ret == MPG123_OK)
ret = mpg123_open_feed(handle);
if (ret != MPG123_OK) {
mpg123_delete(handle);
return 0;
}
std::vector<uint8_t> output_buffer(mpg123_outblock(handle));
size_t output_written = 0;
// Initially, start by feeding the decoder more data.
int decode_ret = MPG123_NEED_MORE;
FuzzedDataProvider provider(data, size);
while ((decode_ret != MPG123_ERR)) {
if (decode_ret == MPG123_NEED_MORE) {
if (provider.remaining_bytes() == 0
|| mpg123_tellframe(handle) > 10000
|| mpg123_tell_stream(handle) > 1<<20) {
break;
}
const size_t next_size = provider.ConsumeIntegralInRange<size_t>(
0,
provider.remaining_bytes());
auto next_input = provider.ConsumeBytes<unsigned char>(next_size);
decode_ret = mpg123_decode(handle, next_input.data(), next_input.size(),
output_buffer.data(), output_buffer.size(),
&output_written);
} else if (decode_ret != MPG123_ERR && decode_ret != MPG123_NEED_MORE) {
decode_ret = mpg123_decode(handle, nullptr, 0, output_buffer.data(),
output_buffer.size(), &output_written);
} else {
// Unhandled mpg123_decode return value.
abort();
}
}
mpg123_delete(handle);
return 0;
}