PR #25185 opened by Marti2203
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25185
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25185.patch

With `data=uphase`, `unwrap()` computes `d = x[FFMIN(i + 1, N)] - x[i]`, so for 
the last element it reads `x[N]`, one float past the end of the `h`-element 
phases array. Any ordinary use triggers it, e.g.

```
ffmpeg -f lavfi -i sine=f=440:d=0.5 -filter_complex 
"[0:a]showspectrum=size=160x64:data=uphase" -frames:v 2 -f null -
```

Valgrind reports `Invalid read of size 4` at `unwrap (avf_showspectrum.c:1346)` 
called from `calc_channel_uphases`. The stray value can also leak into the last 
sample and into the min/max used to scale the column.

The fix clamps the index to `N - 1`, so the last difference is 0 and adds no 
unwrap step. Valgrind is clean with it; in my runs the `uphase` output was the 
same before and after, and `magnitude`/`phase` output is unchanged.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified 
manually.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



From 57debabf9f007f10fdd788f773aa2be0dfef6d60 Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Sun, 18 Oct 2026 19:33:43 +0800
Subject: [PATCH] avfilter/avf_showspectrum: fix out-of-bounds read in unwrap()

For the last element, x[FFMIN(i + 1, N)] read x[N], one past the end of
the phases array, whenever data=uphase is used. Clamp the index to N - 1,
so that the last difference is 0.

Signed-off-by: Martin Mirchev <[email protected]>
---
 libavfilter/avf_showspectrum.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 0345b4458d..144097d503 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1343,7 +1343,7 @@ static void unwrap(float *x, int N, float tol, float *mi, 
float *ma)
     float min = FLT_MAX;
 
     for (int i = 0; i < N; i++) {
-        const float d = x[FFMIN(i + 1, N)] - x[i];
+        const float d = x[FFMIN(i + 1, N - 1)] - x[i];
         const float p = ceilf(fabsf(d) / rng) * rng * (((d < tol) > 0.f) - ((d 
> -tol) > 0.f));
 
         x[i] += p + prev_p;
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to