From 95b192de5d05f3e1542e7b2378cdefbc195f5185 Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Sat, 24 Mar 2012 15:49:34 -0700 Subject: [PATCH] vc1: Do not read from array if index is invalid. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Ronald S. Bultje --- libavcodec/vc1.c | 2 +- libavcodec/vc1data.c | 2 +- libavcodec/vc1data.h | 2 +- libavcodec/vc1dec.c | 22 +++++++++++++++++++--- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 433baa9862..0e218af759 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -492,7 +492,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) int nr, dr; nr = get_bits(gb, 8); dr = get_bits(gb, 4); - if (nr && nr < 8 && dr && dr < 3) { + if (nr > 0 && nr < 8 && dr > 0 && dr < 3) { v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1]; v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000; } diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index 41d8ab9fd1..70cead8b2c 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -84,7 +84,7 @@ const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = { } }; -const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 }, +const int ff_vc1_fps_nr[7] = { 24, 25, 30, 50, 60, 48, 72 }, ff_vc1_fps_dr[2] = { 1000, 1001 }; const uint8_t ff_vc1_pquant_table[3][32] = { /* Implicit quantizer */ diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h index 1d2a4fd554..84e8188b21 100644 --- a/libavcodec/vc1data.h +++ b/libavcodec/vc1data.h @@ -41,7 +41,7 @@ extern const int ff_vc1_ttfrm_to_tt[4]; extern const uint8_t ff_vc1_mv_pmode_table[2][5]; extern const uint8_t ff_vc1_mv_pmode_table2[2][4]; -extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2]; +extern const int ff_vc1_fps_nr[7], ff_vc1_fps_dr[2]; extern const uint8_t ff_vc1_pquant_table[3][32]; /* MBMODE table for interlaced frame P-picture */ diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index a08ad11eb9..409153f168 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -2370,6 +2370,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, int16_t *dc_val; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int q1, q2 = 0; + int dqscale_index; wrap = s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; @@ -2382,15 +2383,18 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, a = dc_val[ - wrap]; /* scale predictors if needed */ q1 = s->current_picture.f.qscale_table[mb_pos]; + dqscale_index = s->y_dc_scale_table[q1] - 1; + if (dqscale_index < 0) + return 0; if (c_avail && (n != 1 && n != 3)) { q2 = s->current_picture.f.qscale_table[mb_pos - 1]; if (q2 && q2 != q1) - c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && (n != 2 && n != 3)) { q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; if (q2 && q2 != q1) - a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail && (n != 3)) { int off = mb_pos; @@ -2400,7 +2404,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, off -= s->mb_stride; q2 = s->current_picture.f.qscale_table[off]; if (q2 && q2 != q1) - b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail) { @@ -2817,6 +2821,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -2859,6 +2865,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -2869,6 +2877,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3027,6 +3037,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -3069,6 +3081,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3079,6 +3093,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; }