Summary
symphonia-metadata 0.6.0 panics with attempt to add with overflow at src/ape.rs:226 when parsing an APEv2 tag header whose size field is near u32::MAX with the header-present flag set. Found by libfuzzer in a ~60-second run against symphonia::default::get_probe().probe().
The bug is present on the current main branch — ape.rs:226 is unchanged (latest touch of that file is 2026-06-07, and the arithmetic there is the same as the published crate).
Vulnerable code
// src/ape.rs — raw u32 from untrusted input
let size = reader.read_u32()?;
// ...
// src/ape.rs:226 — no overflow check
let real_size = size + if has_header { 32 } else { 0 };
Minimized reproducer (36 bytes, hex)
2b e3 e3 41 50 45 54 41 47 45 58 d0 07 00 00 e3
ff ff ff ff e3 ff e3 13 0a ff ff f1 df 41 50 3f
13 a3 0a
| Bytes |
Value |
Meaning |
| 4–11 |
APETAGEX |
APEv2 magic — gates entry to the header reader |
| 12–15 |
d0 07 00 00 (2000 LE) |
APEv2 version branch |
| 16–19 |
e3 ff ff ff |
size = 0xFFFFFFE3 (4294967267) |
| 20–23 |
bit 31 set |
has_header = true |
4294967267 + 32 = 4294967299 > u32::MAX → panic.
Repro
Feed the 36 bytes to symphonia::default::get_probe().probe(...) on untrusted input (APE tags can also ride on MP3, so this is reachable from ordinary audio-file probing).
Suggested fix
// Saturating:
let real_size = size.saturating_add(if has_header { 32 } else { 0 });
// Or explicit rejection:
if size > u32::MAX - 32 {
return decode_error("ape: tag size field overflows u32");
}
let real_size = size + if has_header { 32 } else { 0 };
Happy to open a PR if that's welcome. Thanks for Symphonia!
Summary
symphonia-metadata 0.6.0panics withattempt to add with overflowatsrc/ape.rs:226when parsing an APEv2 tag header whosesizefield is nearu32::MAXwith the header-present flag set. Found by libfuzzer in a ~60-second run againstsymphonia::default::get_probe().probe().The bug is present on the current
mainbranch —ape.rs:226is unchanged (latest touch of that file is 2026-06-07, and the arithmetic there is the same as the published crate).Vulnerable code
Minimized reproducer (36 bytes, hex)
APETAGEXd0 07 00 00(2000 LE)e3 ff ff ffsize = 0xFFFFFFE3(4294967267)has_header = true4294967267 + 32 = 4294967299 > u32::MAX→ panic.Repro
Feed the 36 bytes to
symphonia::default::get_probe().probe(...)on untrusted input (APE tags can also ride on MP3, so this is reachable from ordinary audio-file probing).Suggested fix
Happy to open a PR if that's welcome. Thanks for Symphonia!