mirror of https://git.ffmpeg.org/ffmpeg.git
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>
This commit is contained in:
parent
7b74e02ef2
commit
14226be499
|
@ -88,15 +88,13 @@ typedef struct HeadphoneContext {
|
||||||
} *in;
|
} *in;
|
||||||
} HeadphoneContext;
|
} 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;
|
int len, i, channel_id = 0;
|
||||||
int64_t layout, layout0;
|
int64_t layout, layout0;
|
||||||
|
|
||||||
if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) {
|
if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) {
|
||||||
layout0 = layout = av_get_channel_layout(buf);
|
layout0 = layout = av_get_channel_layout(buf);
|
||||||
if (layout == AV_CH_LOW_FREQUENCY)
|
|
||||||
s->lfe_channel = x;
|
|
||||||
for (i = 32; i > 0; i >>= 1) {
|
for (i = 32; i > 0; i >>= 1) {
|
||||||
if (layout >= 1LL << i) {
|
if (layout >= 1LL << i) {
|
||||||
channel_id += i;
|
channel_id += i;
|
||||||
|
@ -116,6 +114,7 @@ static void parse_map(AVFilterContext *ctx)
|
||||||
{
|
{
|
||||||
HeadphoneContext *s = ctx->priv;
|
HeadphoneContext *s = ctx->priv;
|
||||||
char *arg, *tokenizer, *p, *args = av_strdup(s->map);
|
char *arg, *tokenizer, *p, *args = av_strdup(s->map);
|
||||||
|
uint64_t used_channels = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!args)
|
if (!args)
|
||||||
|
@ -134,10 +133,17 @@ static void parse_map(AVFilterContext *ctx)
|
||||||
char buf[8];
|
char buf[8];
|
||||||
|
|
||||||
p = NULL;
|
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);
|
av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", arg);
|
||||||
continue;
|
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->mapping[s->nb_irs] = out_ch_id;
|
||||||
s->nb_irs++;
|
s->nb_irs++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue