diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp index 09630a70..1a2fec7c 100644 --- a/taglib/mp4/mp4tag.cpp +++ b/taglib/mp4/mp4tag.cpp @@ -111,7 +111,12 @@ MP4::Tag::parseData2(MP4::Atom *atom, TagLib::File *file, int expectedFlags, boo unsigned int pos = 0; while(pos < data.size()) { const int length = static_cast(data.toUInt(pos)); - ByteVector name = data.mid(pos + 4, 4); + if(length < 12) { + debug("MP4: Too short atom"); + return result; + } + + const ByteVector name = data.mid(pos + 4, 4); const int flags = static_cast(data.toUInt(pos + 8)); if(freeForm && i < 2) { if(i == 0 && name != "mean") { @@ -274,7 +279,12 @@ MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file) unsigned int pos = 0; while(pos < data.size()) { const int length = static_cast(data.toUInt(pos)); - ByteVector name = data.mid(pos + 4, 4); + if(length < 12) { + debug("MP4: Too short atom"); + break;; + } + + const ByteVector name = data.mid(pos + 4, 4); const int flags = static_cast(data.toUInt(pos + 8)); if(name != "data") { debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); @@ -296,7 +306,7 @@ MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file) ByteVector MP4::Tag::padIlst(const ByteVector &data, int length) { - if (length == -1) { + if(length == -1) { length = ((data.size() + 1023) & ~1023) - data.size(); } return renderAtom("free", ByteVector(length, '\1')); diff --git a/tests/data/infloop.m4a b/tests/data/infloop.m4a new file mode 100644 index 00000000..bbf76db8 Binary files /dev/null and b/tests/data/infloop.m4a differ diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp index 7e25f996..ac4d4907 100644 --- a/tests/test_mp4.cpp +++ b/tests/test_mp4.cpp @@ -27,6 +27,7 @@ class TestMP4 : public CppUnit::TestFixture CPPUNIT_TEST(testCovrWrite); CPPUNIT_TEST(testCovrRead2); CPPUNIT_TEST(testProperties); + CPPUNIT_TEST(testFuzzedFile); CPPUNIT_TEST_SUITE_END(); public: @@ -282,6 +283,12 @@ public: CPPUNIT_ASSERT_EQUAL(StringList("0"), tags["COMPILATION"]); } + void testFuzzedFile() + { + MP4::File f(TEST_FILE_PATH_C("infloop.m4a")); + CPPUNIT_ASSERT(f.isValid()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);