const uint64_t maxpixels_per_frame = 4096 * 4096;
uint64_t maxpixels;
+uint64_t maxsamples_per_frame = 256*1024*32;
+uint64_t maxsamples;
+
static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const uint8_t *end = data + size;
uint32_t it = 0;
uint64_t ec_pixels = 0;
+ uint64_t nb_samples = 0;
int (*decode_handler)(AVCodecContext *avctx, AVFrame *picture,
int *got_picture_ptr,
const AVPacket *avpkt) = NULL;
AVCodecParserContext *parser = NULL;
-
+ uint64_t keyframes = 0;
+ AVDictionary *opts = NULL;
if (!c) {
#ifdef FFMPEG_DECODER
case AVMEDIA_TYPE_VIDEO : decode_handler = avcodec_decode_video2; break;
case AVMEDIA_TYPE_SUBTITLE: decode_handler = subtitle_handler ; break;
}
+ switch (c->id) {
+ case AV_CODEC_ID_APE: maxsamples_per_frame /= 256; break;
+ }
maxpixels = maxpixels_per_frame * maxiteration;
+ maxsamples = maxsamples_per_frame * maxiteration;
switch (c->id) {
- // Allows a small input to generate gigantic output
- case AV_CODEC_ID_BINKVIDEO: maxpixels /= 32; break;
- case AV_CODEC_ID_DIRAC: maxpixels /= 8192; break;
- case AV_CODEC_ID_MSRLE: maxpixels /= 16; break;
- case AV_CODEC_ID_QTRLE: maxpixels /= 16; break;
- case AV_CODEC_ID_SANM: maxpixels /= 16; break;
- case AV_CODEC_ID_GIF: maxpixels /= 16; break;
- // Performs slow frame rescaling in C
- case AV_CODEC_ID_GDV: maxpixels /= 512; break;
- // Postprocessing in C
- case AV_CODEC_ID_HNM4_VIDEO:maxpixels /= 128; break;
- // Cliping in C, generally slow even with small input
- case AV_CODEC_ID_INDEO4: maxpixels /= 128; break;
- case AV_CODEC_ID_LSCR: maxpixels /= 16; break;
- case AV_CODEC_ID_MOTIONPIXELS:maxpixels /= 256; break;
- case AV_CODEC_ID_SNOW: maxpixels /= 128; break;
- case AV_CODEC_ID_TRUEMOTION2: maxpixels /= 1024; break;
+ case AV_CODEC_ID_BINKVIDEO: maxpixels /= 32; break;
+ case AV_CODEC_ID_CFHD: maxpixels /= 128; break;
+ case AV_CODEC_ID_DIRAC: maxpixels /= 8192; break;
+ case AV_CODEC_ID_DST: maxsamples /= 8192; break;
+ case AV_CODEC_ID_DXV: maxpixels /= 32; break;
+ case AV_CODEC_ID_FFWAVESYNTH: maxsamples /= 16384; break;
+ case AV_CODEC_ID_G2M: maxpixels /= 64; break;
+ case AV_CODEC_ID_GDV: maxpixels /= 512; break;
+ case AV_CODEC_ID_GIF: maxpixels /= 16; break;
+ case AV_CODEC_ID_HNM4_VIDEO: maxpixels /= 128; break;
+ case AV_CODEC_ID_IFF_ILBM: maxpixels /= 128; break;
+ case AV_CODEC_ID_INDEO4: maxpixels /= 128; break;
+ case AV_CODEC_ID_LSCR: maxpixels /= 16; break;
+ case AV_CODEC_ID_MOTIONPIXELS:maxpixels /= 256; break;
+ case AV_CODEC_ID_MP4ALS: maxsamples /= 65536; break;
+ case AV_CODEC_ID_MSRLE: maxpixels /= 16; break;
+ case AV_CODEC_ID_MSS2: maxpixels /= 16384; break;
+ case AV_CODEC_ID_MSZH: maxpixels /= 128; break;
+ case AV_CODEC_ID_QTRLE: maxpixels /= 16; break;
+ case AV_CODEC_ID_RASC: maxpixels /= 16; break;
+ case AV_CODEC_ID_SANM: maxpixels /= 16; break;
+ case AV_CODEC_ID_SCPR: maxpixels /= 32; break;
+ case AV_CODEC_ID_SMACKVIDEO: maxpixels /= 64; break;
+ case AV_CODEC_ID_SNOW: maxpixels /= 128; break;
+ case AV_CODEC_ID_TGV: maxpixels /= 32; break;
+ case AV_CODEC_ID_TRUEMOTION2: maxpixels /= 1024; break;
+ case AV_CODEC_ID_VP7: maxpixels /= 256; break;
+ case AV_CODEC_ID_VP9: maxpixels /= 4096; break;
}
ctx->max_pixels = maxpixels_per_frame; //To reduce false positive OOM and hangs
ctx->refcounted_frames = 1; //To reduce false positive timeouts and focus testing on the refcounted API
+ ctx->max_samples = maxsamples_per_frame;
+
if (size > 1024) {
GetByteContext gbc;
int extradata_size;
+ int flags;
size -= 1024;
bytestream2_init(&gbc, data + size, 1024);
ctx->width = bytestream2_get_le32(&gbc);
ctx->bit_rate = bytestream2_get_le64(&gbc);
ctx->bits_per_coded_sample = bytestream2_get_le32(&gbc);
// Try to initialize a parser for this codec, note, this may fail which just means we test without one
- if (bytestream2_get_byte(&gbc) & 1)
+ flags = bytestream2_get_byte(&gbc);
+ if (flags & 1)
parser = av_parser_init(c->id);
+ if (flags & 2)
+ ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ if (flags & 4) {
+ ctx->err_recognition = AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL;
+ if (flags & 8)
+ ctx->err_recognition |= AV_EF_EXPLODE;
+ }
+ if (flags & 0x10)
+ ctx->flags2 |= AV_CODEC_FLAG2_FAST;
+
+ if (flags & 0x40)
+ av_force_cpu_flags(0);
extradata_size = bytestream2_get_le32(&gbc);
- ctx->sample_rate = bytestream2_get_le32(&gbc);
+ ctx->sample_rate = bytestream2_get_le32(&gbc) & 0x7FFFFFFF;
ctx->channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS;
+ ctx->block_align = bytestream2_get_le32(&gbc) & 0x7FFFFFFF;
+ ctx->codec_tag = bytestream2_get_le32(&gbc);
+ if (c->codec_tags) {
+ int n;
+ for (n = 0; c->codec_tags[n] != FF_CODEC_TAGS_END; n++);
+ ctx->codec_tag = c->codec_tags[ctx->codec_tag % n];
+ }
+ keyframes = bytestream2_get_le64(&gbc);
+ ctx->request_channel_layout = bytestream2_get_le64(&gbc);
+
+ ctx->idct_algo = bytestream2_get_byte(&gbc) % 25;
+
+ if (flags & 0x20) {
+ switch (ctx->codec_id) {
+ case AV_CODEC_ID_AC3:
+ case AV_CODEC_ID_EAC3:
+ av_dict_set_int(&opts, "cons_noisegen", bytestream2_get_byte(&gbc) & 1, 0);
+ av_dict_set_int(&opts, "heavy_compr", bytestream2_get_byte(&gbc) & 1, 0);
+ av_dict_set_int(&opts, "target_level", (int)(bytestream2_get_byte(&gbc) % 32) - 31, 0);
+ av_dict_set_int(&opts, "dmix_mode", (int)(bytestream2_get_byte(&gbc) % 4) - 1, 0);
+ break;
+ }
+ }
+
if (extradata_size < size) {
ctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
ctx->width = ctx->height = 0;
}
- int res = avcodec_open2(ctx, c, NULL);
+ int res = avcodec_open2(ctx, c, &opts);
if (res < 0) {
avcodec_free_context(&ctx);
av_free(parser_avctx);
av_parser_close(parser);
+ av_dict_free(&opts);
return 0; // Failure of avcodec_open2() does not imply that a issue was found
}
parser_avctx->codec_id = ctx->codec_id;
if (res < 0)
error("Failed memory allocation");
memcpy(parsepkt.data, last, data - last);
+ parsepkt.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY;
+ keyframes = (keyframes >> 2) + (keyframes<<62);
data += sizeof(fuzz_tag);
last = data;
av_frame_unref(frame);
int ret = decode_handler(ctx, frame, &got_frame, &avpkt);
- ec_pixels += ctx->width * ctx->height;
+ ec_pixels += (ctx->width + 32LL) * (ctx->height + 32LL);
if (it > 20 || ec_pixels > 4 * ctx->max_pixels)
ctx->error_concealment = 0;
if (ec_pixels > maxpixels)
goto maximums_reached;
+ nb_samples += frame->nb_samples;
+ if (nb_samples > maxsamples)
+ goto maximums_reached;
+
if (ret <= 0 || ret > avpkt.size)
break;
if (ctx->codec_type != AVMEDIA_TYPE_AUDIO)
decode_handler(ctx, frame, &got_frame, &avpkt);
} while (got_frame == 1 && it++ < maxiteration);
- fprintf(stderr, "pixels decoded: %"PRId64", iterations: %d\n", ec_pixels, it);
+ fprintf(stderr, "pixels decoded: %"PRId64", samples decoded: %"PRId64", iterations: %d\n", ec_pixels, nb_samples, it);
av_frame_free(&frame);
avcodec_free_context(&ctx);
avcodec_free_context(&parser_avctx);
av_parser_close(parser);
av_packet_unref(&parsepkt);
+ av_dict_free(&opts);
return 0;
}