From 4f0535ca0c462155b2d3303d33ad501317a887f0 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 5 Jun 2017 23:38:25 +0300 Subject: [PATCH] Add a standalone tool for decoding ffmpeg oss-fuzz samples This tries to replicate the call sequence exercised by the decoding fuzz tests for ffmpeg/oss-fuzz (matching what tools/target_dec_fuzzer.c from ffmpeg does, when calling the libfdk-aac decoder via libavcodec). --- .gitignore | 1 + Makefile.am | 5 ++- fuzz-dec.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 fuzz-dec.c diff --git a/.gitignore b/.gitignore index 263e5aa..006e6be 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ missing stamp-h1 aac-enc compile +fuzz-dec diff --git a/Makefile.am b/Makefile.am index fe6b867..92cc0f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,11 +39,14 @@ libfdk_aac_la_LDFLAGS = -version-info @FDK_AAC_VERSION@ -no-undefined \ -export-symbols $(top_srcdir)/fdk-aac.sym if EXAMPLE -bin_PROGRAMS = aac-enc$(EXEEXT) +bin_PROGRAMS = aac-enc$(EXEEXT) fuzz-dec$(EXEEXT) aac_enc_LDADD = libfdk-aac.la aac_enc_SOURCES = aac-enc.c wavreader.c +fuzz_dec_LDADD = libfdk-aac.la +fuzz_dec_SOURCES = fuzz-dec.c + noinst_HEADERS = wavreader.h endif diff --git a/fuzz-dec.c b/fuzz-dec.c new file mode 100644 index 0000000..fe235d0 --- /dev/null +++ b/fuzz-dec.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include "aacdecoder_lib.h" + +static const uint8_t tag[] = "FUZZ-TAG"; + +static void test(const uint8_t *ptr, int size) { + const uint8_t *base = ptr; + const uint8_t *end = ptr + size; + int tagsize = sizeof(tag) - 1; + + int decoder_buffer_size = 2048 * 2 * 8; + uint8_t *decoder_buffer = malloc(decoder_buffer_size); + + HANDLE_AACDECODER decoder = aacDecoder_Open(TT_MP4_ADTS, 1); + aacDecoder_SetParam(decoder, AAC_CONCEAL_METHOD, 1); + aacDecoder_SetParam(decoder, AAC_PCM_LIMITER_ENABLE, 0); + + while (1) { + const uint8_t* start = ptr; + UINT valid, buffer_size; + AAC_DECODER_ERROR err; + + while (ptr + tagsize < end) { + if (!memcmp(ptr, tag, tagsize)) + break; + ptr++; + } + if (ptr + tagsize > end) + ptr = end; + + do { + valid = buffer_size = ptr - start; + err = aacDecoder_Fill(decoder, (UCHAR**) &start, &buffer_size, &valid); + start += buffer_size - valid; + if (err == AAC_DEC_NOT_ENOUGH_BITS) + continue; + if (err == AAC_DEC_OK) + err = aacDecoder_DecodeFrame(decoder, (INT_PCM *) decoder_buffer, decoder_buffer_size / sizeof(INT_PCM), 0); + if (err != AAC_DEC_NOT_ENOUGH_BITS && err != AAC_DEC_OK) + break; + } while (start < ptr); + + aacDecoder_GetStreamInfo(decoder); + + if (ptr + tagsize <= end) { + ptr += tagsize; + } else { + break; + } + } + while (1) { + const uint8_t* start = NULL; + UINT buffer_size = 0, valid = 0; + AAC_DECODER_ERROR err; + err = aacDecoder_Fill(decoder, (UCHAR**) &start, &buffer_size, &valid); + if (err == AAC_DEC_OK) + err = aacDecoder_DecodeFrame(decoder, (INT_PCM *) decoder_buffer, decoder_buffer_size / sizeof(INT_PCM), 0); + if (err != AAC_DEC_OK) + break; + } + free(decoder_buffer); + aacDecoder_Close(decoder); +} + +int main(int argc, char *argv[]) { + FILE *f; + int size; + uint8_t *buf; + + if (argc < 2) { + printf("%s file\n", argv[0]); + return 0; + } + f = fopen(argv[1], "rb"); + if (!f) { + perror(argv[1]); + return 1; + } + + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + + buf = malloc(size); + if (fread(buf, 1, size, f) == size) + test(buf, size); + free(buf); + + fclose(f); + return 0; +}