af_channelmap: sanity check input channel indices in all cases.
authorAnton Khirnov <anton@khirnov.net>
Sun, 14 Apr 2013 10:07:24 +0000 (12:07 +0200)
committerAnton Khirnov <anton@khirnov.net>
Wed, 17 Apr 2013 06:37:59 +0000 (08:37 +0200)
Fixes invalid reads from non-existing channels.

CC:libav-stable@libav.org

libavfilter/af_channelmap.c

index da83009..c626a21 100644 (file)
@@ -356,23 +356,32 @@ static int channelmap_config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
     ChannelMapContext *s = ctx->priv;
+    int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
     int i, err = 0;
     const char *channel_name;
     char layout_name[256];
 
-    if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
-        for (i = 0; i < s->nch; i++) {
+    for (i = 0; i < s->nch; i++) {
+        if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
             s->map[i].in_channel_idx = av_get_channel_layout_channel_index(
                 inlink->channel_layout, s->map[i].in_channel);
-            if (s->map[i].in_channel_idx < 0) {
+        }
+
+        if (s->map[i].in_channel_idx < 0 ||
+            s->map[i].in_channel_idx >= nb_channels) {
+            av_get_channel_layout_string(layout_name, sizeof(layout_name),
+                                         0, inlink->channel_layout);
+            if (s->map[i].in_channel) {
                 channel_name = av_get_channel_name(s->map[i].in_channel);
-                av_get_channel_layout_string(layout_name, sizeof(layout_name),
-                                             0, inlink->channel_layout);
                 av_log(ctx, AV_LOG_ERROR,
                        "input channel '%s' not available from input layout '%s'\n",
                        channel_name, layout_name);
-                err = AVERROR(EINVAL);
+            } else {
+                av_log(ctx, AV_LOG_ERROR,
+                       "input channel #%d not available from input layout '%s'\n",
+                       s->map[i].in_channel_idx, layout_name);
             }
+            err = AVERROR(EINVAL);
         }
     }