]> granicus.if.org Git - taglib/commitdiff
Fix infinite loops when parsing MP4 files.
authorTsuda Kageyu <tsuda.kageyu@gmail.com>
Thu, 25 Dec 2014 00:32:56 +0000 (09:32 +0900)
committerTsuda Kageyu <tsuda.kageyu@gmail.com>
Wed, 18 Feb 2015 02:33:10 +0000 (11:33 +0900)
taglib/mp4/mp4tag.cpp
tests/data/infloop.m4a [new file with mode: 0644]
tests/test_mp4.cpp

index 09630a7048836bfc0e0a2d7099d7f700dcf26032..1a2fec7c6d9f029484d1b79d967df3755ead9a63 100644 (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'));
diff --git a/tests/data/infloop.m4a b/tests/data/infloop.m4a
new file mode 100644 (file)
index 0000000..bbf76db
Binary files /dev/null and b/tests/data/infloop.m4a differ
index 7e25f9968383107b0e3341f4768c64ce8a42b843..ac4d4907ac5750fc805f61903ac304623cbf2580 100644 (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);