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

Reply via email to