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:
parent
8297853917
commit
be8b796f55
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user