X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fwmv2dec.c;h=a16c4465f0858cdeb0d940ba35f846ffc787d23b;hb=b0a29d88c83facec70f2a0a8941733f88ddde416;hp=ea0e0594b5063fa3c384c2aaffa9b44bbd5f348a;hpb=ce265b0bf5d0c77a092a1f5fbeb652c7cdea5fc7;p=ffmpeg diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c index ea0e0594b50..a16c4465f08 100644 --- a/libavcodec/wmv2dec.c +++ b/libavcodec/wmv2dec.c @@ -33,6 +33,7 @@ static int parse_mb_skip(Wmv2Context *w) { int mb_x, mb_y; + int coded_mb_count = 0; MpegEncContext *const s = &w->s; uint32_t *const mb_type = s->current_picture_ptr->mb_type; @@ -83,6 +84,14 @@ static int parse_mb_skip(Wmv2Context *w) } break; } + + for (mb_y = 0; mb_y < s->mb_height; mb_y++) + for (mb_x = 0; mb_x < s->mb_width; mb_x++) + coded_mb_count += !IS_SKIP(mb_type[mb_y * s->mb_stride + mb_x]); + + if (coded_mb_count > get_bits_left(&s->gb)) + return AVERROR_INVALIDDATA; + return 0; } @@ -141,6 +150,21 @@ int ff_wmv2_decode_picture_header(MpegEncContext *s) if (s->qscale <= 0) return AVERROR_INVALIDDATA; + if (s->pict_type != AV_PICTURE_TYPE_I && show_bits(&s->gb, 1)) { + GetBitContext gb = s->gb; + int skip_type = get_bits(&gb, 2); + int run = skip_type == SKIP_TYPE_COL ? s->mb_width : s->mb_height; + + while (run > 0) { + int block = FFMIN(run, 25); + if (get_bits(&gb, block) + 1 != 1<dc_table_index = get_bits1(&s->gb); + + // at minimum one bit per macroblock is required at least in a valid frame, + // we discard frames much smaller than this. Frames smaller than 1/8 of the + // smallest "black/skip" frame generally contain not much recoverable content + // while at the same time they have the highest computational requirements + // per byte + if (get_bits_left(&s->gb) * 8LL < (s->width+15)/16 * ((s->height+15)/16)) + return AVERROR_INVALIDDATA; } s->inter_intra_pred = 0; s->no_rounding = 1; @@ -207,6 +239,9 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s) s->rl_chroma_table_index = s->rl_table_index; } + if (get_bits_left(&s->gb) < 2) + return AVERROR_INVALIDDATA; + s->dc_table_index = get_bits1(&s->gb); s->mv_table_index = get_bits1(&s->gb); @@ -502,6 +537,7 @@ AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, };