Fix infinite loops when parsing MP4 files.

This commit is contained in:
Tsuda Kageyu 2014-12-25 09:32:56 +09:00
parent f6081ed32e
commit b69973bcf2
3 changed files with 20 additions and 3 deletions

View File

@ -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<int>(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<int>(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<int>(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<int>(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'));

BIN
tests/data/infloop.m4a Normal file

Binary file not shown.

View File

@ -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);