From 3094540a4baab58af530333182a198e8fe854c83 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Fri, 22 May 2015 14:11:06 +0900 Subject: [PATCH] Avoid an infinite loop when reading fuzzed WavPack files. (#482) --- taglib/wavpack/wavpackproperties.cpp | 41 +++++++++++++-------------- tests/data/infloop.wv | Bin 0 -> 2462 bytes tests/test_wavpack.cpp | 5 ++++ 3 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 tests/data/infloop.wv diff --git a/taglib/wavpack/wavpackproperties.cpp b/taglib/wavpack/wavpackproperties.cpp index 085ddf8a..ec12282d 100644 --- a/taglib/wavpack/wavpackproperties.cpp +++ b/taglib/wavpack/wavpackproperties.cpp @@ -176,28 +176,25 @@ void WavPack::Properties::read() unsigned int WavPack::Properties::seekFinalIndex() { - ByteVector blockID("wvpk", 4); + const long offset = d->file->rfind("wvpk", d->streamLength); + if(offset == -1) + return 0; - 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; - } + d->file->seek(offset); + const ByteVector data = d->file->readBlock(32); + if(data.size() < 32) + return 0; - 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 index 0000000000000000000000000000000000000000..d8c720cfe06ede7b8275d051730591dc34bf3f26 GIT binary patch literal 2462 zcmXRfE68TZU|?WnVPN_!atrxq1w=I1FyJBB&C=t6>q2Qz3O{`Yh-RzUT?WZ3`zK>tI`M)g0?=@|YuO3f?6 z?f;_GR7bG?Ne7VPHB{?iOmn7`1=ncAOHX(ah;a{ literal 0 HcmV?d00001 diff --git a/tests/test_wavpack.cpp b/tests/test_wavpack.cpp index 085fa2da..e9f891cc 100644 --- a/tests/test_wavpack.cpp +++ b/tests/test_wavpack.cpp @@ -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);