[FFmpeg-cvslog] avcodec/eac3dec: Check that channel_map does not contain more than EAC3_MAX_CHANNELS

Michael Niedermayer git at videolan.org
Sat Sep 22 03:00:20 EEST 2018


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Wed Jun 27 14:43:39 2018 +0200| [fe315feab59f2f99765547096357826bc9454d24] | committer: Michael Niedermayer

avcodec/eac3dec: Check that channel_map does not contain more than EAC3_MAX_CHANNELS

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fe315feab59f2f99765547096357826bc9454d24
---

 libavcodec/ac3dec.c  | 27 ++++-----------------------
 libavcodec/ac3tab.c  | 18 ++++++++++++++++++
 libavcodec/ac3tab.h  |  2 ++
 libavcodec/eac3dec.c | 14 ++++++++++++--
 4 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index ea7e052f8b..eed8ce5b39 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
@@ -1700,7 +1681,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) {
@@ -1714,9 +1695,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;
                     if (extend >= channel_map_size)
@@ -1727,7 +1708,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;
         }
     }
 



More information about the ffmpeg-cvslog mailing list