Skip to content

Commit

Permalink
riff,wav: Handle unexpected extensible format chunks (#250)
Browse files Browse the repository at this point in the history
Some WAVE files encode a WAVEFORMATEXTENSIBLE structure in 
their format chunk, but don't set the format to extensible, or the
extra data length to the required value. This is a violation of the WAVE
specification, but can be supported with little trouble.

Fixes #247.
  • Loading branch information
dedobbin authored Jan 15, 2024
1 parent cc7fe3a commit 4e8a098
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
22 changes: 14 additions & 8 deletions symphonia-format-riff/src/wave/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,21 @@ impl WaveFormatChunk {
) -> Result<FormatData> {
// WaveFormat for a IEEE format should not be extended, but it may still have an extra data
// length parameter.
if len == 18 {
let extra_size = reader.read_u16()?;

if extra_size != 0 {
return decode_error("wav: extra data not expected for fmt_ieee chunk");
match len {
16 => (),
18 => {
let extra_size = reader.read_u16()?;
if extra_size != 0 {
return decode_error("wav: extra data not expected for fmt_ieee chunk");
}
}
}
else if len > 16 {
return decode_error("wav: malformed fmt_ieee chunk");
40 => {
// WAVEFORMATEXTENSIBLE is used for formats having more than two channels
// or higher sample resolutions than allowed by WAVEFORMATEX but for now
// we just ignore it
let _ = reader.ignore_bytes(40 - 16);
}
_ => return decode_error("wav: malformed fmt_ieee chunk"),
}

// Officially, only 32-bit floats are supported, but Symphonia can handle 64-bit floats.
Expand Down
22 changes: 14 additions & 8 deletions symphonia-format-wav/src/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,21 @@ impl WaveFormatChunk {
) -> Result<WaveFormatData> {
// WaveFormat for a IEEE format should not be extended, but it may still have an extra data
// length parameter.
if len == 18 {
let extra_size = reader.read_u16()?;

if extra_size != 0 {
return decode_error("wav: extra data not expected for fmt_ieee chunk");
match len {
16 => (),
18 => {
let extra_size = reader.read_u16()?;
if extra_size != 0 {
return decode_error("wav: extra data not expected for fmt_ieee chunk");
}
}
}
else if len > 16 {
return decode_error("wav: malformed fmt_ieee chunk");
40 => {
// WAVEFORMATEXTENSIBLE is used for formats having more than two channels
// or higher sample resolutions than allowed by WAVEFORMATEX but for now
// we just ignore it
let _ = reader.ignore_bytes(40 - 16);
}
_ => return decode_error("wav: malformed fmt_ieee chunk"),
}

// Officially, only 32-bit floats are supported, but Symphonia can handle 64-bit floats.
Expand Down

0 comments on commit 4e8a098

Please sign in to comment.