X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fwcmv.c;h=2988c15b23acfd3b53faedf3581fece640de1759;hb=06476249cd2332e30b66576633b2827adf3478dd;hp=233427f3fa5c2e5176cee2a1b686ae061660c593;hpb=64425e005edf3bdd77c34c078c3e74ab5ecef557;p=ffmpeg diff --git a/libavcodec/wcmv.c b/libavcodec/wcmv.c index 233427f3fa5..2988c15b23a 100644 --- a/libavcodec/wcmv.c +++ b/libavcodec/wcmv.c @@ -56,21 +56,13 @@ static int decode_frame(AVCodecContext *avctx, } bytestream2_init(&gb, avpkt->data, avpkt->size); + blocks = bytestream2_get_le16(&gb); + if (!blocks) + return avpkt->size; if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - if (s->prev_frame->data[0]) { - ret = av_frame_copy(frame, s->prev_frame); - if (ret < 0) - return ret; - } else { - ptrdiff_t linesize[4] = { frame->linesize[0], 0, 0, 0 }; - av_image_fill_black(frame->data, linesize, avctx->pix_fmt, 0, - avctx->width, avctx->height); - } - - blocks = bytestream2_get_le16(&gb); if (blocks > 5) { GetByteContext bgb; int x = 0, size; @@ -113,6 +105,8 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&bgb, 4); w = bytestream2_get_le16(&bgb); h = bytestream2_get_le16(&bgb); + if (x + bpp * (int64_t)w * h > INT_MAX) + return AVERROR_INVALIDDATA; x += bpp * w * h; } @@ -140,6 +134,8 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&gb, 4); w = bytestream2_get_le16(&gb); h = bytestream2_get_le16(&gb); + if (x + bpp * (int64_t)w * h > INT_MAX) + return AVERROR_INVALIDDATA; x += bpp * w * h; } @@ -158,6 +154,16 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_seek(&gb, 2, SEEK_SET); } + if (s->prev_frame->data[0]) { + ret = av_frame_copy(frame, s->prev_frame); + if (ret < 0) + return ret; + } else { + ptrdiff_t linesize[4] = { frame->linesize[0], 0, 0, 0 }; + av_image_fill_black(frame->data, linesize, avctx->pix_fmt, 0, + avctx->width, avctx->height); + } + for (int block = 0; block < blocks; block++) { int x, y, w, h; @@ -209,7 +215,7 @@ static av_cold int decode_init(AVCodecContext *avctx) int zret; switch (avctx->bits_per_coded_sample) { - case 16: avctx->pix_fmt = AV_PIX_FMT_RGB565; break; + case 16: avctx->pix_fmt = AV_PIX_FMT_RGB565LE; break; case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break; case 32: avctx->pix_fmt = AV_PIX_FMT_BGRA; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported bits_per_coded_sample: %d\n",