PR #24100 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24100 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24100.patch
Fixes: ffmpeg -i tail.wav -i ir.wav -filter_complex "[0][1]afir=dry=1:wet=1:enable='lte(t,0.5)'" -f null - Fixes: out of array access Fixes: uQcNui1HxUqe Regression since: 1835f884b7ae475d2079d044003966981823502e Found-by: Eunsoo Kim, Microsoft FORGE Labs # Summary of changes Briefly describe what this PR does and why. <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From a1a7f6b543373f036156fe896e8c78ecc99e7863 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Wed, 12 Aug 2026 01:57:57 +0200 Subject: [PATCH] avfilter/afir: bound the crossfades by the samples of the input frame Fixes: ffmpeg -i tail.wav -i ir.wav -filter_complex "[0][1]afir=dry=1:wet=1:enable='lte(t,0.5)'" -f null - Fixes: out of array access Fixes: uQcNui1HxUqe Regression since: 1835f884b7ae475d2079d044003966981823502e Found-by: Eunsoo Kim, Microsoft FORGE Labs --- libavfilter/afir_template.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavfilter/afir_template.c b/libavfilter/afir_template.c index c45b29902e..10dc677c20 100644 --- a/libavfilter/afir_template.c +++ b/libavfilter/afir_template.c @@ -140,7 +140,7 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int ioffs const ftype *in = (const ftype *)s->in->extended_data[ch] + ioffset; ftype *blockout, *ptr = (ftype *)out->extended_data[ch] + offset; const int min_part_size = s->min_part_size; - const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset); + const int nb_samples = FFMIN(min_part_size, s->in->nb_samples - ioffset); const int nb_segments = s->nb_segments[selir]; const float dry_gain = s->dry_gain; const float wet_gain = s->wet_gain; @@ -246,6 +246,8 @@ static void fn(fir_quantums)(AVFilterContext *ctx, AudioFIRContext *s, AVFrame * int min_part_size, int ch, int offset, int prev_selir, int selir) { + const int nb_samples = FFMIN(min_part_size, s->in->nb_samples - offset); + if (ctx->is_disabled || s->prev_is_disabled) { const ftype *in = (const ftype *)s->in->extended_data[ch] + offset; const ftype *xfade0 = (const ftype *)s->xfade[0]->extended_data[ch]; @@ -257,15 +259,15 @@ static void fn(fir_quantums)(AVFilterContext *ctx, AudioFIRContext *s, AVFrame * if (ctx->is_disabled && !s->prev_is_disabled) { memset(src0, 0, min_part_size * sizeof(ftype)); fn(fir_quantum)(ctx, s->fadein[0], ch, offset, 0, selir); - for (int n = 0; n < min_part_size; n++) + for (int n = 0; n < nb_samples; n++) dst[n] = xfade1[n] * src0[n] + xfade0[n] * in[n]; } else if (!ctx->is_disabled && s->prev_is_disabled) { memset(src1, 0, min_part_size * sizeof(ftype)); fn(fir_quantum)(ctx, s->fadein[1], ch, offset, 0, selir); - for (int n = 0; n < min_part_size; n++) + for (int n = 0; n < nb_samples; n++) dst[n] = xfade1[n] * in[n] + xfade0[n] * src1[n]; } else { - memcpy(dst, in, sizeof(ftype) * min_part_size); + memcpy(dst, in, sizeof(ftype) * nb_samples); } } else if (prev_selir != selir && s->loading[ch] != 0) { const ftype *xfade0 = (const ftype *)s->xfade[0]->extended_data[ch]; @@ -281,11 +283,11 @@ static void fn(fir_quantums)(AVFilterContext *ctx, AudioFIRContext *s, AVFrame * fn(fir_quantum)(ctx, s->fadein[1], ch, offset, 0, selir); if (s->loading[ch] > s->max_offset[selir]) { - for (int n = 0; n < min_part_size; n++) + for (int n = 0; n < nb_samples; n++) dst[n] = xfade1[n] * src0[n] + xfade0[n] * src1[n]; s->loading[ch] = 0; } else { - memcpy(dst, src0, min_part_size * sizeof(ftype)); + memcpy(dst, src0, nb_samples * sizeof(ftype)); } } else { fn(fir_quantum)(ctx, out, ch, offset, offset, selir); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
