aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2013-07-14 14:06:16 +0200
committerLuca Barbato <lu_zero@gentoo.org>2013-09-29 21:41:49 +0200
commita0b8f85f29883f538a32593bc3c6f712c972ff70 (patch)
tree1b6c84ac527be70650148cd14ec541ea8bc606e3 /libavcodec
parentc02b9e6e633896617e5f95211665c5521800498b (diff)
downloadffmpeg-a0b8f85f29883f538a32593bc3c6f712c972ff70.tar.gz
indeo: Bound-check before applying motion compensation
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 25a6666f6c07c6ac8449a63d7fbce0dfd29c54cd) Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/ivi_common.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index ea9082cadd..5289d6c766 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -42,16 +42,22 @@ VLC ff_ivi_blk_vlc_tabs[8];
typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf,
uint32_t pitch, int mc_type);
-static int ivi_mc(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf,
- int offs, int mv_x, int mv_y, uint32_t pitch,
- int mc_type)
+static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc,
+ int offs, int mv_x, int mv_y, int mc_type)
{
- int ref_offs = offs + mv_y * pitch + mv_x;
+ int ref_offs = offs + mv_y * band->pitch + mv_x;
+ int buf_size = band->pitch * band->aheight;
+ int min_size = band->pitch * (band->blk_size - 1) + band->blk_size;
+ int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1);
- if (offs < 0 || ref_offs < 0 || !ref_buf)
+ if (offs < 0 || ref_offs < 0 || !band->ref_buf)
+ return AVERROR_INVALIDDATA;
+ if (buf_size - min_size < offs)
+ return AVERROR_INVALIDDATA;
+ if (buf_size - min_size - ref_size < ref_offs)
return AVERROR_INVALIDDATA;
- mc(buf + offs, ref_buf + ref_offs, pitch, mc_type);
+ mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type);
return 0;
}
@@ -464,8 +470,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band,
/* apply motion compensation */
if (!is_intra)
- return ivi_mc(mc, band->buf, band->ref_buf, offs, mv_x, mv_y,
- band->pitch, mc_type);
+ return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type);
return 0;
}
@@ -555,8 +560,8 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
if (ret < 0)
return ret;
} else {
- ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf,
- buf_offs, mv_x, mv_y, band->pitch, mc_type);
+ ret = ivi_mc(band, mc_no_delta_func, buf_offs,
+ mv_x, mv_y, mc_type);
if (ret < 0)
return ret;
}
@@ -662,8 +667,8 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
for (blk = 0; blk < num_blocks; blk++) {
/* adjust block position in the buffer according with its number */
offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
- ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf,
- offs, mv_x, mv_y, band->pitch, mc_type);
+ ret = ivi_mc(band, mc_no_delta_func, offs,
+ mv_x, mv_y, mc_type);
if (ret < 0)
return ret;
}