From: "Ronald S. Bultje" <[email protected]> Prevents subsequent overreads when these numbers are used as indices in arrays.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: [email protected] --- libavcodec/qdm2.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 6acb7d8..c0dc488 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -336,15 +336,18 @@ static av_cold void qdm2_init_vlc(void) } } -static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) +static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth, int range) { int value; value = get_vlc2(gb, vlc->table, vlc->bits, depth); /* stage-2, 3 bits exponent escape sequence */ - if (value-- == 0) + if (value-- == 0) { value = get_bits (gb, get_bits (gb, 3) + 1); + if (range) + value = av_clip(value, 0, range - 1); + } /* stage-3, optional */ if (flag) { @@ -361,7 +364,7 @@ static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) { - int value = qdm2_get_vlc (gb, vlc, 0, depth); + int value = qdm2_get_vlc (gb, vlc, 0, depth, 0); return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); } @@ -885,7 +888,8 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l case 30: if (BITS_LEFT(length,gb) >= 4) - samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; + samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1, + FF_ARRAY_ELEMS(type30_dequant))]; else samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); @@ -900,7 +904,8 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l type34_predictor = samples[0]; type34_first = 0; } else { - samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; + samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1, + FF_ARRAY_ELEMS(type34_delta))] / type34_div + type34_predictor; type34_predictor = samples[0]; } } else { @@ -954,14 +959,14 @@ static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext if (BITS_LEFT(length,gb) < 16) return; - level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2); + level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2, 0); quantized_coeffs[0] = level; for (i = 0; i < 7; ) { if (BITS_LEFT(length,gb) < 16) break; - run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1; + run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1, 0) + 1; if (BITS_LEFT(length,gb) < 16) break; @@ -1009,7 +1014,7 @@ static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb, i for (k=0; k < 8; k++) { if (BITS_LEFT(length,gb) < 16) break; - q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi1, 0, 2); + q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi1, 0, 2, 0); } } else { for (k=0; k < 8; k++) @@ -1023,7 +1028,7 @@ static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb, i for (ch = 0; ch < q->nb_channels; ch++) { if (BITS_LEFT(length,gb) < 16) break; - q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi2, 0, 2); + q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi2, 0, 2, 0); if (sb > 19) q->tone_level_idx_hi2[ch][sb] -= 16; else @@ -1038,7 +1043,7 @@ static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb, i for (j = 0; j < 8; j++) { if (BITS_LEFT(length,gb) < 16) break; - q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_mid, 0, 2) - 32; + q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_mid, 0, 2, 0) - 32; } } @@ -1059,11 +1064,11 @@ static void process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) for (i = 1; i < n; i++) for (ch=0; ch < q->nb_channels; ch++) { - level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); + level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2, 0); q->quantized_coeffs[ch][i][0] = level; for (j = 0; j < (8 - 1); ) { - run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; + run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1, 0) + 1; diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); for (k = 1; k <= run; k++) @@ -1278,7 +1283,7 @@ static void qdm2_decode_super_block (QDM2Context *q) q->fft_level_exp[j] = get_bits(&gb, 6); } else if (packet->type == 14) { for (j = 0; j < 6; j++) - q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2); + q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2, 0); } else if (packet->type == 15) { SAMPLES_NEEDED_2("packet type 15") return; @@ -1333,7 +1338,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * while (1) { if (q->superblocktype_2_3) { - while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { + while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2, 0)) < 2) { offset = 1; if (n == 0) { local_int_4 += local_int_10; @@ -1345,7 +1350,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * } offset += (n - 2); } else { - offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); + offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2, 0); while (offset >= (local_int_10 - 1)) { offset += (1 - (local_int_10 - 1)); local_int_4 += local_int_10; @@ -1368,7 +1373,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * stereo = 0; } - exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); + exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2, 0); exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; exp = (exp < 0) ? 0 : exp; @@ -1377,8 +1382,8 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * stereo_phase = 0; if (stereo) { - stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); - stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); + stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1, 0)); + stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1, 0)); if (stereo_phase < 0) stereo_phase += 8; } -- 1.7.9.2 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
