Skip over INFO chunk in WAV files (#1862)

This commit is contained in:
Mark Thompson 2024-02-07 14:37:49 -06:00 committed by GitHub
parent 8ad9ada015
commit c5bf0d94f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -27,8 +27,10 @@ bool WAVFileReader::open(const std::filesystem::path& path) {
size_t i = 0; size_t i = 0;
char ch; char ch;
const uint8_t tag_INAM[4] = {'I', 'N', 'A', 'M'}; const uint8_t tag_INAM[4] = {'I', 'N', 'A', 'M'};
const uint8_t tag_data[4] = {'d', 'a', 't', 'a'};
struct data_t data_header;
char title_buffer[32]{0}; char title_buffer[32]{0};
uint32_t riff_size, data_end, title_size; uint32_t riff_size, inam_search_start, title_size;
size_t search_limit = 0; size_t search_limit = 0;
// Already open ? // Already open ?
@ -45,17 +47,34 @@ bool WAVFileReader::open(const std::filesystem::path& path) {
auto error = file_.open(path); auto error = file_.open(path);
if (!error.is_valid()) { if (!error.is_valid()) {
file_.read((void*)&header, sizeof(header)); // Read header (RIFF and WAVE) if (!file_.read((void*)&header, sizeof(header)).is_ok()) // Read header (RIFF and WAVE)
return false;
// TODO: Work needed here to process RIFF file format correctly, i.e. properly skip over LIST & INFO chunks // Assuming here that RIFF & WAV & fmt chunk ID's are all correct...
riff_size = header.cksize + 8; riff_size = 8 + header.cksize;
data_start = header.fmt.cksize + 28;
data_size_ = header.data.cksize; // check for the "data" chunk ID
data_end = data_start + data_size_ + 1; if (memcmp(header.data.ckID, tag_data, 4) == 0) {
data_start = 20 + header.fmt.cksize + 8;
data_size_ = header.data.cksize;
inam_search_start = data_start + data_size_;
} else {
// data header wasn't where we guessed; skip over one unexpected chunk (perhaps LIST/INFO/INAM)
inam_search_start = 20 + header.fmt.cksize;
file_.seek(20 + header.fmt.cksize + 8 + header.data.cksize);
if (!file_.read((void*)&data_header, sizeof(data_header)).is_ok())
return false;
if (memcmp(data_header.ckID, tag_data, 4) == 0) {
data_start = 20 + header.fmt.cksize + 8 + header.data.cksize + 8;
data_size_ = data_header.cksize;
} else
return false;
}
// Look for INAM (title) tag // Look for INAM (title) tag
if (data_end < riff_size) { if (inam_search_start < riff_size) {
file_.seek(data_end); file_.seek(inam_search_start);
while (file_.read((void*)&ch, 1).is_ok()) { while (file_.read((void*)&ch, 1).is_ok()) {
if (ch == tag_INAM[i++]) { if (ch == tag_INAM[i++]) {
if (i == 4) { if (i == 4) {