X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Favs.c;h=05cb815fd884a58b90b36cb1d16395ad12889e4b;hb=c48883163d6c7ff0806687bf3ee33ca9f8e7dede;hp=14f7cf050792fb53b9b17fab9044d2f06464d47b;hpb=0cb233cf46e057c4d4d9352470305de3f569a036;p=ffmpeg diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 14f7cf05079..05cb815fd88 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -47,6 +47,7 @@ avs_decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; @@ -62,13 +63,15 @@ avs_decode_frame(AVCodecContext * avctx, av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } - p->reference = 1; + p->reference = 3; p->pict_type = AV_PICTURE_TYPE_P; p->key_frame = 0; out = avs->picture.data[0]; stride = avs->picture.linesize[0]; + if (buf_end - buf < 4) + return AVERROR_INVALIDDATA; sub_type = buf[0]; type = buf[1]; buf += 4; @@ -79,9 +82,13 @@ avs_decode_frame(AVCodecContext * avctx, first = AV_RL16(buf); last = first + AV_RL16(buf + 2); + if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first)) + return AVERROR_INVALIDDATA; buf += 4; - for (i=first; i> 6) & 0x30303; + } sub_type = buf[0]; type = buf[1]; @@ -114,16 +121,22 @@ avs_decode_frame(AVCodecContext * avctx, return -1; } + if (buf_end - buf < 256 * vect_w * vect_h) + return AVERROR_INVALIDDATA; table = buf + (256 * vect_w * vect_h); if (sub_type != AVS_I_FRAME) { int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h); - init_get_bits(&change_map, table, map_size); + if (buf_end - table < map_size) + return AVERROR_INVALIDDATA; + init_get_bits(&change_map, table, map_size * 8); table += map_size; } for (y=0; y<198; y+=vect_h) { for (x=0; x<318; x+=vect_w) { if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) { + if (buf_end - table < 1) + return AVERROR_INVALIDDATA; vect = &buf[*table++ * (vect_w * vect_h)]; for (j=0; jpriv_data; + if (s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + return 0; +} + + AVCodec ff_avs_decoder = { .name = "avs", .type = AVMEDIA_TYPE_VIDEO, @@ -159,6 +181,7 @@ AVCodec ff_avs_decoder = { .priv_data_size = sizeof(AvsContext), .init = avs_decode_init, .decode = avs_decode_frame, + .close = avs_decode_end, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"), };