]> granicus.if.org Git - taglib/commitdiff
Avoid an infinite loop when reading fuzzed WavPack files. (#482)
authorTsuda Kageyu <tsuda.kageyu@gmail.com>
Fri, 22 May 2015 05:11:06 +0000 (14:11 +0900)
committerTsuda Kageyu <tsuda.kageyu@gmail.com>
Fri, 22 May 2015 05:15:10 +0000 (14:15 +0900)
taglib/wavpack/wavpackproperties.cpp
tests/data/infloop.wv [new file with mode: 0644]
tests/test_wavpack.cpp

index 085ddf8a4707bcfba30fa8bcd24569a87bd67109..ec12282daf525325e2e982f64d05ffcb2ac17dfd 100644 (file)
@@ -176,28 +176,25 @@ void WavPack::Properties::read()
 
 unsigned int WavPack::Properties::seekFinalIndex()
 {
-  ByteVector blockID("wvpk", 4);
-
-  long offset = d->streamLength;
-  while(offset > 0) {
-    offset = d->file->rfind(blockID, offset);
-    if(offset == -1)
-      return 0;
-    d->file->seek(offset);
-    ByteVector data = d->file->readBlock(32);
-    if(data.size() != 32)
-      return 0;
-    const int version = data.toShort(8, false);
-    if(version < MIN_STREAM_VERS || version > MAX_STREAM_VERS)
-      continue;
-    const unsigned int flags = data.toUInt(24, false);
-    if(!(flags & FINAL_BLOCK))
-      return 0;
-    const unsigned int blockIndex   = data.toUInt(16, false);
-    const unsigned int blockSamples = data.toUInt(20, false);
-    return blockIndex + blockSamples;
-  }
+  const long offset = d->file->rfind("wvpk", d->streamLength);
+  if(offset == -1)
+    return 0;
 
-  return 0;
-}
+  d->file->seek(offset);
+  const ByteVector data = d->file->readBlock(32);
+  if(data.size() < 32)
+    return 0;
+
+  const int version = data.toShort(8, false);
+  if(version < MIN_STREAM_VERS || version > MAX_STREAM_VERS)
+    return 0;
 
+  const unsigned int flags = data.toUInt(24, false);
+  if(!(flags & FINAL_BLOCK))
+    return 0;
+
+  const unsigned int blockIndex   = data.toUInt(16, false);
+  const unsigned int blockSamples = data.toUInt(20, false);
+
+  return blockIndex + blockSamples;
+}
diff --git a/tests/data/infloop.wv b/tests/data/infloop.wv
new file mode 100644 (file)
index 0000000..d8c720c
Binary files /dev/null and b/tests/data/infloop.wv differ
index 085fa2daa2fb3d0bd9a246a3de6756cebc3e5819..e9f891ccab8c9b0a2de81d19d2b0df2e43ded87d 100644 (file)
@@ -35,6 +35,11 @@ public:
     CPPUNIT_ASSERT_EQUAL(4, props->length());
   }
 
+  void testFuzzedFile()
+  {
+    WavPack::File f(TEST_FILE_PATH_C("infloop.wv"));
+    CPPUNIT_ASSERT(f.isValid());
+  }
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestWavPack);