From 85f4fb88fb5ffb4af26489ddd53492820aaa7400 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Fri, 17 May 2019 15:00:21 +0300 Subject: [PATCH] Try to replicate the ffmpeg fuzzer's behaviour with parsers and extradata --- .gitignore | 1 + Makefile.am | 8 +++++ configure.ac | 9 ++++++ fuzz-dec.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 006e6be..9d929cb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ stamp-h1 aac-enc compile fuzz-dec +fuzz-dec-lavc diff --git a/Makefile.am b/Makefile.am index 92cc0f9..317bd22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,14 @@ aac_enc_SOURCES = aac-enc.c wavreader.c fuzz_dec_LDADD = libfdk-aac.la fuzz_dec_SOURCES = fuzz-dec.c +if HAVE_LIBAVCODEC +bin_PROGRAMS += fuzz-dec-lavc$(EXEEXT) + +fuzz_dec_lavc_LDADD = $(libavcodec_LIBS) $(libavutil_LIBS) libfdk-aac.la +fuzz_dec_lavc_CFLAGS = $(libavcodec_CFLAGS) $(libavutil_CFLAGS) -DHAVE_LIBAVCODEC +fuzz_dec_lavc_SOURCES = fuzz-dec.c +endif + noinst_HEADERS = wavreader.h endif diff --git a/configure.ac b/configure.ac index 597120a..cc58ec1 100644 --- a/configure.ac +++ b/configure.ac @@ -13,8 +13,14 @@ AC_ARG_ENABLE([example], [enable example encoding program (default is no)])], [example=$enableval], [example=no]) +if test x$example = xyes; then + PKG_CHECK_MODULES([libavcodec], [libavcodec], [libavcodec=yes], [libavcodec=no]) + PKG_CHECK_MODULES([libavutil], [libavutil], [libavutil=yes], [libavutil=no]) +fi + dnl Automake conditionals to set AM_CONDITIONAL(EXAMPLE, test x$example = xyes) +AM_CONDITIONAL(HAVE_LIBAVCODEC, test x$libavcodec = xyes) dnl Checks for programs. AC_PROG_CC @@ -36,3 +42,6 @@ AC_SUBST(LIBS_PRIVATE) AC_CONFIG_FILES([Makefile fdk-aac.pc]) AC_OUTPUT +if test x$example = xyes; then + AC_MSG_NOTICE([Found libavcodec: ${libavcodec}]) +fi diff --git a/fuzz-dec.c b/fuzz-dec.c index fe235d0..549af78 100644 --- a/fuzz-dec.c +++ b/fuzz-dec.c @@ -3,6 +3,10 @@ #include #include #include "aacdecoder_lib.h" +#ifdef HAVE_LIBAVCODEC +#include +#include +#endif static const uint8_t tag[] = "FUZZ-TAG"; @@ -14,10 +18,38 @@ static void test(const uint8_t *ptr, int size) { int decoder_buffer_size = 2048 * 2 * 8; uint8_t *decoder_buffer = malloc(decoder_buffer_size); - HANDLE_AACDECODER decoder = aacDecoder_Open(TT_MP4_ADTS, 1); + int extradata_size = 0; + uint8_t *extradata = NULL; +#ifdef HAVE_LIBAVCODEC + AVCodecParserContext *parser = NULL; + AVCodecContext *avctx = NULL; + if (size > 1024) { + const uint8_t* params = ptr + size - 1024; + size -= 1024; + params += 20; // width, height, bit_rate, bits_per_coded_sample + uint8_t flags = *params++; + if (flags & 1) { + parser = av_parser_init(AV_CODEC_ID_AAC); + avctx = avcodec_alloc_context3(NULL); + } + extradata_size = AV_RL32(params); + params += 4; + if (extradata_size < size) { + extradata = malloc(extradata_size); + size -= extradata_size; + memcpy(extradata, ptr + size, extradata_size); + } + } +#endif + + HANDLE_AACDECODER decoder = aacDecoder_Open(extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1); aacDecoder_SetParam(decoder, AAC_CONCEAL_METHOD, 1); aacDecoder_SetParam(decoder, AAC_PCM_LIMITER_ENABLE, 0); + if (extradata_size) { + aacDecoder_ConfigRaw(decoder, &extradata, &extradata_size); + } + while (1) { const uint8_t* start = ptr; UINT valid, buffer_size; @@ -31,19 +63,34 @@ static void test(const uint8_t *ptr, int size) { 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); + while (start < ptr) { + const uint8_t *input = start; + const uint8_t *inputend = ptr; +#ifdef HAVE_LIBAVCODEC + if (parser) { + int parse_size; + int ret = av_parser_parse2(parser, avctx, (uint8_t**) &input, &parse_size, start, ptr - start, 0, 0, 0); + start += ret; + inputend = input + parse_size; + } else +#endif + start = ptr; + + while (input && input < inputend) { + valid = buffer_size = inputend - input; + err = aacDecoder_Fill(decoder, (UCHAR**) &input, &buffer_size, &valid); + input += 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; + } + + aacDecoder_GetStreamInfo(decoder); + } if (ptr + tagsize <= end) { ptr += tagsize; @@ -63,6 +110,13 @@ static void test(const uint8_t *ptr, int size) { } free(decoder_buffer); aacDecoder_Close(decoder); + free(extradata); +#ifdef HAVE_LIBAVCODEC + if (parser) { + av_parser_close(parser); + avcodec_free_context(&avctx); + } +#endif } int main(int argc, char *argv[]) { @@ -70,6 +124,10 @@ int main(int argc, char *argv[]) { int size; uint8_t *buf; +#ifdef HAVE_LIBAVCODEC + avcodec_register_all(); +#endif + if (argc < 2) { printf("%s file\n", argv[0]); return 0;