Proper handling of MP4 atoms with zero length.

If the size of an atom is 0, it designates the last atom which extends to the end of the file.
This commit is contained in:
Tsuda Kageyu 2016-11-02 15:44:50 +09:00
parent eb6d058ab9
commit f5ca097379
3 changed files with 18 additions and 2 deletions

View File

@ -54,10 +54,15 @@ MP4::Atom::Atom(File *file)
length = header.toUInt();
if(length == 1) {
if(length == 0) {
// The last atom which extends to the end of the file.
length = file->length() - offset;
}
else if(length == 1) {
// The atom has a 64-bit length.
const long long longLength = file->readBlock(8).toLongLong();
if(longLength <= LONG_MAX) {
// The atom has a 64-bit length, but it's actually a 31-bit value or long is 64-bit.
// The actual length fits in long. That's always the case if long is 64-bit.
length = static_cast<long>(longLength);
}
else {
@ -67,6 +72,7 @@ MP4::Atom::Atom(File *file)
return;
}
}
if(length < 8) {
debug("MP4: Invalid atom size");
length = 0;

Binary file not shown.

View File

@ -57,6 +57,7 @@ class TestMP4 : public CppUnit::TestFixture
CPPUNIT_TEST(testProperties);
CPPUNIT_TEST(testFuzzedFile);
CPPUNIT_TEST(testRepeatedSave);
CPPUNIT_TEST(testWithZeroLengthAtom);
CPPUNIT_TEST_SUITE_END();
public:
@ -395,6 +396,15 @@ public:
CPPUNIT_ASSERT_EQUAL(2862L, f.find("0123456789"));
CPPUNIT_ASSERT_EQUAL(-1L, f.find("0123456789", 2863));
}
void testWithZeroLengthAtom()
{
MP4::File f(TEST_FILE_PATH_C("zero-length-mdat.m4a"));
CPPUNIT_ASSERT(f.isValid());
CPPUNIT_ASSERT_EQUAL(1115, f.audioProperties()->lengthInMilliseconds());
CPPUNIT_ASSERT_EQUAL(22050, f.audioProperties()->sampleRate());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);