diff --git a/taglib/riff/wav/infotag.cpp b/taglib/riff/wav/infotag.cpp index 7cd2a192..050ff37c 100644 --- a/taglib/riff/wav/infotag.cpp +++ b/taglib/riff/wav/infotag.cpp @@ -258,9 +258,15 @@ void RIFF::Info::Tag::parse(const ByteVector &data) uint p = 4; while(p < data.size()) { const uint size = data.toUInt(p + 4, false); - d->fieldListMap[data.mid(p, 4)] = TagPrivate::stringHandler->parse(data.mid(p + 8, size)); + if(size > data.size() - p - 8) + break; + + const ByteVector id = data.mid(p, 4); + if(isValidChunkID(id)) { + const String text = TagPrivate::stringHandler->parse(data.mid(p + 8, size)); + d->fieldListMap[id] = text; + } p += ((size + 1) & ~1) + 8; } } - diff --git a/taglib/riff/wav/wavproperties.cpp b/taglib/riff/wav/wavproperties.cpp index 8062df5f..439a1954 100644 --- a/taglib/riff/wav/wavproperties.cpp +++ b/taglib/riff/wav/wavproperties.cpp @@ -115,6 +115,11 @@ TagLib::uint RIFF::WAV::Properties::sampleFrames() const void RIFF::WAV::Properties::read(const ByteVector &data) { + if(data.size() < 16) { + debug("RIFF::WAV::Properties::read() - \"fmt \" chunk is too short for WAV."); + return; + } + d->format = data.toShort(0, false); d->channels = data.toShort(2, false); d->sampleRate = data.toUInt(4, false); diff --git a/tests/data/infloop.wav b/tests/data/infloop.wav new file mode 100644 index 00000000..c220baa8 Binary files /dev/null and b/tests/data/infloop.wav differ diff --git a/tests/data/segfault.wav b/tests/data/segfault.wav new file mode 100644 index 00000000..0385e99b Binary files /dev/null and b/tests/data/segfault.wav differ diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index 518f37cf..7367357a 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -15,6 +15,8 @@ class TestWAV : public CppUnit::TestFixture CPPUNIT_TEST(testLength); CPPUNIT_TEST(testZeroSizeDataChunk); CPPUNIT_TEST(testStripTags); + CPPUNIT_TEST(testFuzzedFile1); + CPPUNIT_TEST(testFuzzedFile2); CPPUNIT_TEST_SUITE_END(); public: @@ -67,7 +69,19 @@ public: CPPUNIT_ASSERT(!f->hasID3v2Tag()); CPPUNIT_ASSERT(f->hasInfoTag()); delete f; - } + } + + void testFuzzedFile1() + { + RIFF::WAV::File f1(TEST_FILE_PATH_C("infloop.wav")); + CPPUNIT_ASSERT(!f1.isValid()); + } + + void testFuzzedFile2() + { + RIFF::WAV::File f2(TEST_FILE_PATH_C("segfault.wav")); + CPPUNIT_ASSERT(f2.isValid()); + } };