diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2020-08-24 06:34:17 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2021-02-27 07:21:00 +0100 |
commit | d5992cc1556380852e406f566f56dc250a993123 (patch) | |
tree | 48fed27a04353f517d38998bc7df485c76f8c72d /libavfilter | |
parent | 9d82a7c813a14d741f4164b689111e80dde3bad6 (diff) | |
download | ffmpeg-d5992cc1556380852e406f566f56dc250a993123.tar.gz |
avfilter/af_headphone: Don't overrun array
The headphone filter stores the channel position of the ith HRIR stream
in the ith element of an array of 64 elements; but because there is no
check for duplicate channels, it is easy to write beyond the end of the
array by simply repeating channels.
This commit adds a check for duplicate channels to rule this out.
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 14226be499d27935d54981f0a6e1b15fd65746cd)
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/af_headphone.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index ec5faf3da7..30e300b5e0 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -88,15 +88,13 @@ typedef struct HeadphoneContext { } *in; } HeadphoneContext; -static int parse_channel_name(HeadphoneContext *s, int x, char **arg, int *rchannel, char *buf) +static int parse_channel_name(char **arg, int *rchannel, char *buf) { int len, i, channel_id = 0; int64_t layout, layout0; if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { layout0 = layout = av_get_channel_layout(buf); - if (layout == AV_CH_LOW_FREQUENCY) - s->lfe_channel = x; for (i = 32; i > 0; i >>= 1) { if (layout >= 1LL << i) { channel_id += i; @@ -116,6 +114,7 @@ static void parse_map(AVFilterContext *ctx) { HeadphoneContext *s = ctx->priv; char *arg, *tokenizer, *p, *args = av_strdup(s->map); + uint64_t used_channels = 0; int i; if (!args) @@ -134,10 +133,17 @@ static void parse_map(AVFilterContext *ctx) char buf[8]; p = NULL; - if (parse_channel_name(s, s->nb_irs, &arg, &out_ch_id, buf)) { + if (parse_channel_name(&arg, &out_ch_id, buf)) { av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", arg); continue; } + if (used_channels & (1ULL << out_ch_id)) { + av_log(ctx, AV_LOG_WARNING, "Ignoring duplicate channel '%s'.\n", buf); + continue; + } + used_channels |= 1ULL << out_ch_id; + if (out_ch_id == av_log2(AV_CH_LOW_FREQUENCY)) + s->lfe_channel = s->nb_irs; s->mapping[s->nb_irs] = out_ch_id; s->nb_irs++; } |