jstrait / wavefile

A Ruby gem for reading and writing sound files in Wave format (*.wav)
https://wavefilegem.com
MIT License
209 stars 24 forks source link

Sample Data Can't Be Read From a WAVE_FORMAT_EXTENSIBLE File With an Oversized Format Chunk Extension #37

Closed jstrait closed 1 year ago

jstrait commented 2 years ago

If a *.wav file's fmt chunk has a format code of 65534 (i.e. WAVE_FORMAT_EXTENSIBLE), it should have a fmt chunk extension at least 22 bytes long. However, as of v1.1.1 sample data can't be read from a WAVE_FORMAT_EXTENSIBLE file where the chunk extension is larger than 22 bytes. Although a Reader instance can be created for such a file, the Reader.format.sub_audio_format_guid field will have an incorrect value, and Reader.readable_format? will be set to false. Any attempts to read sample data will raise an error.

The "sub format GUID" field is 16 bytes long and exists at bytes 6-21 (0-based) of the chunk extension. The bug is that the gem reads from byte 6 until the end of the chunk extension to get this value, instead of just bytes 6-21. If the extension is larger than 22 bytes, this results in a value that is larger than 16 bytes, and is not recognized as valid. Since this value is needed to know how to read sample data out of the data chunk, no sample data can be read from the file.

You might ask, is a WAVE_FORMAT_EXTENSIBLE chunk extension larger than 22 bytes even valid? Yes, according to the document that defines the WAVE_FORMAT_EXTENSIBLE format (https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653308(v=vs.85)). It states that the chunk extension must be at least 22 bytes long. (Search for the "cbSize is at Least 22" heading in that document for more info). This implies that a WAVE_FORMAT_EXTENSIBLE file with a format chunk extension larger than 22 bytes should be valid and readable, with the extra bytes beyond the first 22 being ignored. (As long as the main fmt chunk size also correctly accounts for the oversized extension).

Note that this is similar to the bug described in #34, but not the same. That bug refers to Reader instances incorrectly being able to be created for WAVE_FORMAT_EXTENSIBLE files with a format chunk extension shorter than 22 bytes, instead of raising InvalidFormatError.

This is also similar but not the same as the bug described in #33. That bug refers to issues caused by extra bytes occurring after the format chunk extension, while this issue refers to extra bytes inside the format chunk extension. The behavior is not the same for these two cases.

jstrait commented 1 year ago

This is now fixed in v1.1.2, so closing this issue.