avcodec/wmv2dec: Check end of bitstream in parse_mb_skip() and ff_wmv2_decode_mb()

Fixes: Timeout
Fixes: 3200/clusterfuzz-testcase-5750022136135680

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2017-09-17 01:28:07 +02:00
parent f3af34f9eb
commit 65e0a7c473

View File

@ -30,7 +30,7 @@
#include "wmv2.h" #include "wmv2.h"
static void parse_mb_skip(Wmv2Context *w) static int parse_mb_skip(Wmv2Context *w)
{ {
int mb_x, mb_y; int mb_x, mb_y;
MpegEncContext *const s = &w->s; MpegEncContext *const s = &w->s;
@ -45,6 +45,8 @@ static void parse_mb_skip(Wmv2Context *w)
MB_TYPE_16x16 | MB_TYPE_L0; MB_TYPE_16x16 | MB_TYPE_L0;
break; break;
case SKIP_TYPE_MPEG: case SKIP_TYPE_MPEG:
if (get_bits_left(&s->gb) < s->mb_height * s->mb_width)
return AVERROR_INVALIDDATA;
for (mb_y = 0; mb_y < s->mb_height; mb_y++) for (mb_y = 0; mb_y < s->mb_height; mb_y++)
for (mb_x = 0; mb_x < s->mb_width; mb_x++) for (mb_x = 0; mb_x < s->mb_width; mb_x++)
mb_type[mb_y * s->mb_stride + mb_x] = mb_type[mb_y * s->mb_stride + mb_x] =
@ -52,6 +54,8 @@ static void parse_mb_skip(Wmv2Context *w)
break; break;
case SKIP_TYPE_ROW: case SKIP_TYPE_ROW:
for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
if (get_bits_left(&s->gb) < 1)
return AVERROR_INVALIDDATA;
if (get_bits1(&s->gb)) { if (get_bits1(&s->gb)) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) for (mb_x = 0; mb_x < s->mb_width; mb_x++)
mb_type[mb_y * s->mb_stride + mb_x] = mb_type[mb_y * s->mb_stride + mb_x] =
@ -65,6 +69,8 @@ static void parse_mb_skip(Wmv2Context *w)
break; break;
case SKIP_TYPE_COL: case SKIP_TYPE_COL:
for (mb_x = 0; mb_x < s->mb_width; mb_x++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
if (get_bits_left(&s->gb) < 1)
return AVERROR_INVALIDDATA;
if (get_bits1(&s->gb)) { if (get_bits1(&s->gb)) {
for (mb_y = 0; mb_y < s->mb_height; mb_y++) for (mb_y = 0; mb_y < s->mb_height; mb_y++)
mb_type[mb_y * s->mb_stride + mb_x] = mb_type[mb_y * s->mb_stride + mb_x] =
@ -77,6 +83,7 @@ static void parse_mb_skip(Wmv2Context *w)
} }
break; break;
} }
return 0;
} }
static int decode_ext_header(Wmv2Context *w) static int decode_ext_header(Wmv2Context *w)
@ -170,9 +177,12 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
} }
} else { } else {
int cbp_index; int cbp_index;
int ret;
w->j_type = 0; w->j_type = 0;
parse_mb_skip(w); ret = parse_mb_skip(w);
if (ret < 0)
return ret;
cbp_index = decode012(&s->gb); cbp_index = decode012(&s->gb);
w->cbp_table_index = wmv2_get_cbp_table_index(s, cbp_index); w->cbp_table_index = wmv2_get_cbp_table_index(s, cbp_index);
@ -359,6 +369,8 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
w->hshift = 0; w->hshift = 0;
return 0; return 0;
} }
if (get_bits_left(&s->gb) <= 0)
return AVERROR_INVALIDDATA;
code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table,
MB_NON_INTRA_VLC_BITS, 3); MB_NON_INTRA_VLC_BITS, 3);
@ -369,6 +381,8 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
cbp = code & 0x3f; cbp = code & 0x3f;
} else { } else {
s->mb_intra = 1; s->mb_intra = 1;
if (get_bits_left(&s->gb) <= 0)
return AVERROR_INVALIDDATA;
code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
if (code < 0) { if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, av_log(s->avctx, AV_LOG_ERROR,