From dfa33bec0806cbb45785accb8cc6c2048a7d40cf Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sun, 5 Nov 2023 14:40:18 +0100 Subject: [PATCH] Fix crash with invalid WAV files (#1163) (#1164) With specially crafted WAV files having the "id3 " chunk as the only valid chunk, when trying to write the tags, the existing "id3 " chunk is removed, and then vector::front() is called on the now empty chunks vector. Now it is checked if the vector is empty to avoid the crash. --- taglib/riff/rifffile.cpp | 3 +++ tests/data/invalid-chunk.wav | Bin 0 -> 40 bytes tests/test_wav.cpp | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 tests/data/invalid-chunk.wav diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp index 702fce1a..5e9450e7 100644 --- a/taglib/riff/rifffile.cpp +++ b/taglib/riff/rifffile.cpp @@ -361,6 +361,9 @@ void RIFF::File::writeChunk(const ByteVector &name, const ByteVector &data, void RIFF::File::updateGlobalSize() { + if(d->chunks.empty()) + return; + const Chunk first = d->chunks.front(); const Chunk last = d->chunks.back(); d->size = static_cast(last.offset + last.size + last.padding - first.offset + 12); diff --git a/tests/data/invalid-chunk.wav b/tests/data/invalid-chunk.wav new file mode 100644 index 0000000000000000000000000000000000000000..0ee14fab0a319f8017f3c1b934b5de9e94384124 GIT binary patch literal 40 vcmWIYbaS&{VPFV%40Fv)F;-w=U|{(Fzb&yO;r}NF22U4b28JL{HwOj);O7fO literal 0 HcmV?d00001 diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index 8c81a2bb..01bdf340 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -59,6 +59,7 @@ class TestWAV : public CppUnit::TestFixture CPPUNIT_TEST(testStripAndProperties); CPPUNIT_TEST(testPCMWithFactChunk); CPPUNIT_TEST(testWaveFormatExtensible); + CPPUNIT_TEST(testInvalidChunk); CPPUNIT_TEST_SUITE_END(); public: @@ -385,6 +386,23 @@ public: CPPUNIT_ASSERT_EQUAL(1, f.audioProperties()->format()); } + void testInvalidChunk() + { + ScopedFileCopy copy("invalid-chunk", ".wav"); + + { + RIFF::WAV::File f(copy.fileName().c_str()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->lengthInSeconds()); + CPPUNIT_ASSERT(f.hasID3v2Tag()); + f.ID3v2Tag()->setTitle("Title"); + f.save(); + } + { + RIFF::WAV::File f(copy.fileName().c_str()); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); + } + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestWAV);