[FFmpeg-devel,1/8] avcodec/eac3dec: Check that channel_map does not contain more than EAC3_MAX_CHANNELS

Submitted by Michael Niedermayer on June 27, 2018, 6:11 p.m.

Details

Message ID 20180627181121.30735-1-michael@niedermayer.cc
State New
Headers show

Commit Message

Michael Niedermayer June 27, 2018, 6:11 p.m.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/ac3dec.c  | 27 ++++-----------------------
 libavcodec/ac3tab.c  | 18 ++++++++++++++++++
 libavcodec/ac3tab.h  |  2 ++
 libavcodec/eac3dec.c | 14 ++++++++++++--
 4 files changed, 36 insertions(+), 25 deletions(-)

Comments

Michael Niedermayer Sept. 21, 2018, 12:12 p.m.
On Wed, Jun 27, 2018 at 08:11:14PM +0200, Michael Niedermayer wrote:
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/ac3dec.c  | 27 ++++-----------------------
>  libavcodec/ac3tab.c  | 18 ++++++++++++++++++
>  libavcodec/ac3tab.h  |  2 ++
>  libavcodec/eac3dec.c | 14 ++++++++++++--
>  4 files changed, 36 insertions(+), 25 deletions(-)

will apply

[...]

Patch hide | download patch | download mbox

diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index dfa025cbcc..b1239a1845 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -106,25 +106,6 @@  static const uint8_t ac3_default_coeffs[8][5][2] = {
     { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
 };
 
-static const uint64_t custom_channel_map_locations[16][2] = {
-    { 1, AV_CH_FRONT_LEFT },
-    { 1, AV_CH_FRONT_CENTER },
-    { 1, AV_CH_FRONT_RIGHT },
-    { 1, AV_CH_SIDE_LEFT },
-    { 1, AV_CH_SIDE_RIGHT },
-    { 0, AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER },
-    { 0, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
-    { 0, AV_CH_BACK_CENTER },
-    { 0, AV_CH_TOP_CENTER },
-    { 0, AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT },
-    { 0, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
-    { 0, AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT},
-    { 0, AV_CH_TOP_FRONT_CENTER },
-    { 0, AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT },
-    { 0, AV_CH_LOW_FREQUENCY_2 },
-    { 1, AV_CH_LOW_FREQUENCY },
-};
-
 /**
  * Symmetrical Dequantization
  * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
@@ -1699,7 +1680,7 @@  dependent_frame:
         channel_layout = ich_layout;
         for (ch = 0; ch < 16; ch++) {
             if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
-                channel_layout |= custom_channel_map_locations[ch][1];
+                channel_layout |= ff_eac3_custom_channel_map_locations[ch][1];
             }
         }
         if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) {
@@ -1713,9 +1694,9 @@  dependent_frame:
 
         for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) {
             if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
-                if (custom_channel_map_locations[ch][0]) {
+                if (ff_eac3_custom_channel_map_locations[ch][0]) {
                     int index = av_get_channel_layout_channel_index(channel_layout,
-                                                                    custom_channel_map_locations[ch][1]);
+                                                                    ff_eac3_custom_channel_map_locations[ch][1]);
                     if (index < 0)
                         return AVERROR_INVALIDDATA;
                     extended_channel_map[index] = offset + channel_map[extend++];
@@ -1723,7 +1704,7 @@  dependent_frame:
                     int i;
 
                     for (i = 0; i < 64; i++) {
-                        if ((1LL << i) & custom_channel_map_locations[ch][1]) {
+                        if ((1LL << i) & ff_eac3_custom_channel_map_locations[ch][1]) {
                             int index = av_get_channel_layout_channel_index(channel_layout,
                                                                             1LL << i);
                             if (index < 0)
diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c
index d62d8bfbf5..bd88f32d92 100644
--- a/libavcodec/ac3tab.c
+++ b/libavcodec/ac3tab.c
@@ -314,3 +314,21 @@  const uint16_t ff_eac3_default_chmap[8] = {
     AC3_CHMAP_L |               AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR,
     AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR |                  AC3_CHMAP_R_SUR
 };
+const uint64_t ff_eac3_custom_channel_map_locations[16][2] = {
+    { 1, AV_CH_FRONT_LEFT },
+    { 1, AV_CH_FRONT_CENTER },
+    { 1, AV_CH_FRONT_RIGHT },
+    { 1, AV_CH_SIDE_LEFT },
+    { 1, AV_CH_SIDE_RIGHT },
+    { 0, AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER },
+    { 0, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
+    { 0, AV_CH_BACK_CENTER },
+    { 0, AV_CH_TOP_CENTER },
+    { 0, AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT },
+    { 0, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
+    { 0, AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT},
+    { 0, AV_CH_TOP_FRONT_CENTER },
+    { 0, AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT },
+    { 0, AV_CH_LOW_FREQUENCY_2 },
+    { 1, AV_CH_LOW_FREQUENCY },
+};
diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h
index ade6fb15e7..aa71acbce1 100644
--- a/libavcodec/ac3tab.h
+++ b/libavcodec/ac3tab.h
@@ -50,6 +50,8 @@  extern const uint16_t ff_ac3_fast_gain_tab[8];
 extern const uint16_t ff_eac3_default_chmap[8];
 extern const uint8_t  ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1];
 extern const uint8_t  ff_ac3_bin_to_band_tab[253];
+extern const uint64_t ff_eac3_custom_channel_map_locations[16][2];
+
 
 /** Custom channel map locations bitmask
  *  Other channels described in documentation:
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index fe97d29032..73067ded9d 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -349,8 +349,18 @@  static int ff_eac3_parse_header(AC3DecodeContext *s)
     /* dependent stream channel map */
     if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
         if (get_bits1(gbc)) {
-            s->channel_map = get_bits(gbc, 16);
-            av_log(s->avctx, AV_LOG_DEBUG, "channel_map: %0X\n", s->channel_map);
+            int64_t channel_layout = 0;
+            int channel_map = get_bits(gbc, 16);
+            av_log(s->avctx, AV_LOG_DEBUG, "channel_map: %0X\n", channel_map);
+
+            for (i = 0; i < 16; i++)
+                if (channel_map & (1 << (EAC3_MAX_CHANNELS - i - 1)))
+                    channel_layout |= ff_eac3_custom_channel_map_locations[i][1];
+
+            if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) {
+                return AVERROR_INVALIDDATA;
+            }
+            s->channel_map = channel_map;
         }
     }