vcr1: add sanity checks

Fixes invalid reads with corrupted files.

Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
(cherry picked from commit 8aba7968dd604aae91ee42cbce0be3dad7dceb30)
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>

Conflicts:
	libavcodec/vcr1.c
This commit is contained in:
Anton Khirnov 2013-08-24 21:30:46 +02:00 committed by Luca Barbato
parent 8297853917
commit be8b796f55

View File

@ -64,9 +64,13 @@ static int decode_frame(AVCodecContext *avctx,
p->pict_type= AV_PICTURE_TYPE_I;
p->key_frame= 1;
if (buf_size < 32)
goto packet_small;
for(i=0; i<16; i++){
a->delta[i]= *(bytestream++);
bytestream++;
buf_size--;
}
for(y=0; y<avctx->height; y++){
@ -77,8 +81,12 @@ static int decode_frame(AVCodecContext *avctx,
uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
if (buf_size < 4 + avctx->width)
goto packet_small;
for(i=0; i<4; i++)
a->offset[i]= *(bytestream++);
buf_size -= 4;
offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
for(x=0; x<avctx->width; x+=4){
@ -92,8 +100,12 @@ static int decode_frame(AVCodecContext *avctx,
*(cr++) = bytestream[1];
bytestream+= 4;
buf_size -= 4;
}
}else{
if (buf_size < avctx->width / 2)
goto packet_small;
offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
for(x=0; x<avctx->width; x+=8){
@ -107,6 +119,7 @@ static int decode_frame(AVCodecContext *avctx,
luma[7]=( offset += a->delta[ bytestream[1]>>4 ]);
luma += 8;
bytestream+= 4;
buf_size -= 4;
}
}
}
@ -115,6 +128,9 @@ static int decode_frame(AVCodecContext *avctx,
*data_size = sizeof(AVPicture);
return buf_size;
packet_small:
av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n");
return AVERROR_INVALIDDATA;
}
#if CONFIG_VCR1_ENCODER
@ -151,6 +167,11 @@ static av_cold int decode_init(AVCodecContext *avctx){
avctx->pix_fmt= PIX_FMT_YUV410P;
if (avctx->width & 7) {
av_log(avctx, AV_LOG_ERROR, "Width %d is not divisble by 8.\n", avctx->width);
return AVERROR_INVALIDDATA;
}
return 0;
}