diff --git a/taglib/mpeg/id3v2/id3v2header.cpp b/taglib/mpeg/id3v2/id3v2header.cpp index b3c0472a..18d9cfe0 100644 --- a/taglib/mpeg/id3v2/id3v2header.cpp +++ b/taglib/mpeg/id3v2/id3v2header.cpp @@ -201,12 +201,19 @@ void Header::parse(const ByteVector &data) if(std::any_of(sizeData.cbegin(), sizeData.cend(), [](unsigned char size) { return size >= 128; })) { d->tagSize = 0; - debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the id3v2 header was greater than the allowed 128."); + debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the ID3v2 header was greater than the allowed 128."); return; } // The first three bytes, data[0..2], are the File Identifier, "ID3". (structure 3.1 "file identifier") + // 3.1 states: "Version or revision will never be $FF." + if(static_cast(data[3]) == 0xFF || static_cast(data[4]) == 0xFF) { + d->tagSize = 0; + debug("TagLib::ID3v2::Header::parse() - The version or revision in the ID3v2 header was 0xFF."); + return; + } + // Read the version number from the fourth and fifth bytes. d->majorVersion = data[3]; // (structure 3.1 "major version") d->revisionNumber = data[4]; // (structure 3.1 "revision number") diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp index ba3d9272..efa1b0ef 100644 --- a/tests/test_id3v2.cpp +++ b/tests/test_id3v2.cpp @@ -139,6 +139,7 @@ class TestID3v2 : public CppUnit::TestFixture CPPUNIT_TEST(testEmptyFrame); CPPUNIT_TEST(testDuplicateTags); CPPUNIT_TEST(testParseTOCFrameWithManyChildren); + CPPUNIT_TEST(testInvalidID3v2Version); CPPUNIT_TEST_SUITE_END(); public: @@ -1739,6 +1740,21 @@ public: CPPUNIT_ASSERT(tocFrame->embeddedFrameList().isEmpty()); } + void testInvalidID3v2Version() + { + ID3v2::Header invalidVersionHeader(ByteVector("ID3" + "\xFF\x00" + "\x05" + "\x14\x4F\x00\x32", 10)); + CPPUNIT_ASSERT_EQUAL(invalidVersionHeader.tagSize(), 0U); + + ID3v2::Header invalidRevisionHeader(ByteVector("ID3" + "\x04\xFF" + "\x05" + "\x14\x4F\x00\x32", 10)); + CPPUNIT_ASSERT_EQUAL(invalidRevisionHeader.tagSize(), 0U); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);