From ecff5acb5a738fcb4f9e206a12070dac4bf259b3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 8 Apr 2013 22:15:54 +0200 Subject: [PATCH] svq1dec: clip motion vectors to the frame size. Fixes invalid reads for corrupted files. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC:libav-stable@libav.org --- libavcodec/svq1dec.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 156b960859..4d03bac21d 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -322,7 +322,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous, static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -352,10 +353,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, motion[x / 8 + 2].y = motion[x / 8 + 3].y = mv.y; - if (y + (mv.y >> 1) < 0) - mv.y = 0; - if (x + (mv.x >> 1) < 0) - mv.x = 0; + mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16)); + mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16)); src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch]; dst = current; @@ -367,7 +366,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint8_t *src; uint8_t *dst; @@ -427,10 +427,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, int mvy = pmv[i]->y + (i >> 1) * 16; // FIXME: clipping or padding? - if (y + (mvy >> 1) < 0) - mvy = 0; - if (x + (mvx >> 1) < 0) - mvx = 0; + mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8)); + mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8)); src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch]; dst = current; @@ -450,7 +448,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf, static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, GetBitContext *bitbuf, uint8_t *current, uint8_t *previous, - int pitch, svq1_pmv *motion, int x, int y) + int pitch, svq1_pmv *motion, int x, int y, + int width, int height) { uint32_t block_type; int result = 0; @@ -475,7 +474,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER: result = svq1_motion_inter_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); @@ -486,7 +485,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp, case SVQ1_BLOCK_INTER_4V: result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous, - pitch, motion, x, y); + pitch, motion, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); @@ -703,7 +702,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, result = svq1_decode_delta_block(avctx, &s->dsp, &s->gb, ¤t[x], previous, linesize, - pmv, x, y); + pmv, x, y, width, height); if (result != 0) { av_dlog(avctx, "Error in svq1_decode_delta_block %i\n",