diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2017-03-02 03:02:06 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-05-20 03:41:32 +0200 |
commit | 4e30560efc8ba3ee8e82e2b07b7e8b3fda740e45 (patch) | |
tree | 78ac07496612b8da87f6d1b5c20a7ba54c79b1d6 /libavcodec | |
parent | 94d1f07c3b05d86a476c4f7ffdc7b4e5534de85c (diff) | |
download | ffmpeg-4e30560efc8ba3ee8e82e2b07b7e8b3fda740e45.tar.gz |
avcodec/vp56: Require a correctly decoded frame before using vp56_conceal_mb()
Fixes timeout with 700/clusterfuzz-testcase-5660909504561152
Fixes timeout with 702/clusterfuzz-testcase-4553541576294400
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 2ce4f28431623cdde4aa496fd10430f6c7bdef63)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/vp56.c | 14 | ||||
-rw-r--r-- | libavcodec/vp56.h | 3 |
2 files changed, 16 insertions, 1 deletions
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 5ea365375b..0010408847 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -617,8 +617,12 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } + s->discard_frame = 0; avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1); + if (s->discard_frame) + return AVERROR_INVALIDDATA; + if ((res = av_frame_ref(data, p)) < 0) return res; *got_frame = 1; @@ -704,8 +708,13 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, for (mb_col=0; mb_col<s->mb_width; mb_col++) { if (!damaged) { int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha); - if (ret < 0) + if (ret < 0) { damaged = 1; + if (!s->have_undamaged_frame) { + s->discard_frame = 1; + return AVERROR_INVALIDDATA; + } + } } if (damaged) vp56_conceal_mb(s, mb_row, mb_col, is_alpha); @@ -722,6 +731,9 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data, } } + if (!damaged) + s->have_undamaged_frame = 1; + next: if (p->key_frame || s->golden_frame) { av_frame_unref(s->frames[VP56_FRAME_GOLDEN]); diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 34d48228fd..e5c5bea963 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -203,6 +203,9 @@ struct vp56_context { VLC runv_vlc[2]; VLC ract_vlc[2][3][6]; unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ + + int have_undamaged_frame; + int discard_frame; }; |