From 6c602170a991ff32e3ac5ec07bb88a2334f63902 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Wed, 10 Jun 2026 15:24:31 -0400 Subject: [PATCH] fix(audio): guard EXTENSIBLE fmt OOB read on truncated buffer; document padded-container gap --- DeepDrftContent/Processors/AudioProcessor.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/DeepDrftContent/Processors/AudioProcessor.cs b/DeepDrftContent/Processors/AudioProcessor.cs index 90acd40..fce5fae 100644 --- a/DeepDrftContent/Processors/AudioProcessor.cs +++ b/DeepDrftContent/Processors/AudioProcessor.cs @@ -174,6 +174,11 @@ public class AudioProcessor return new WavValidationResult { IsValid = false, ErrorMessage = "Invalid data: EXTENSIBLE fmt chunk too small" }; } + if (fmtChunkPos + 8 + 40 > buffer.Length) + { + return new WavValidationResult { IsValid = false, ErrorMessage = "Invalid data: EXTENSIBLE fmt chunk extends past end of file" }; + } + // SubFormat GUID begins 24 bytes into the fmt chunk data (fmtChunkPos + 8 + 24). Its // first two bytes are the little-endian format tag; 0x0001 == WAVE_FORMAT_PCM. var subFormatPos = fmtChunkPos + 8 + 24; @@ -220,6 +225,9 @@ public class AudioProcessor // For EXTENSIBLE the offset-22 field is the container width; the true sample depth lives in // wValidBitsPerSample (fmtChunkPos + 8 + 18). They usually match (Bandcamp 24-bit = 24/24) // but the valid bits are authoritative for the normalized header and metadata. + // Note: padded-container EXTENSIBLE (e.g. 24-bit valid in a 32-bit container) is not yet + // supported — the mismatched BlockAlign will cause ValidateAudioParameters to throw and fall + // back to defaults. This is an accepted gap as of this fix. if (validation.IsExtensible) { bitsPerSample = BitConverter.ToUInt16(buffer, validation.FmtChunkPos + 8 + 18);