From 2dd6931eee2ab502cb636d96357b885eaec5084a Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sun, 6 Dec 2020 08:56:35 +0100 Subject: [PATCH] Accept WAV files with garbage appended (#973) This will allow editing the tags of WAV files which have data appended at the end. The corresponding unit test checks that the original contents are still available after editing the metadata of such files. --- taglib/riff/rifffile.cpp | 2 -- tests/test_aiff.cpp | 4 ++-- tests/test_wav.cpp | 46 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp index d3e1aa21..005551f4 100644 --- a/taglib/riff/rifffile.cpp +++ b/taglib/riff/rifffile.cpp @@ -302,13 +302,11 @@ void RIFF::File::read() if(!isValidChunkName(chunkName)) { debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid ID"); - setValid(false); break; } if(static_cast(offset) + 8 + chunkSize > length()) { debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)"); - setValid(false); break; } diff --git a/tests/test_aiff.cpp b/tests/test_aiff.cpp index 116c13a6..0337729f 100644 --- a/tests/test_aiff.cpp +++ b/tests/test_aiff.cpp @@ -148,13 +148,13 @@ public: void testFuzzedFile1() { RIFF::AIFF::File f(TEST_FILE_PATH_C("segfault.aif")); - CPPUNIT_ASSERT(!f.isValid()); + CPPUNIT_ASSERT(f.isValid()); } void testFuzzedFile2() { RIFF::AIFF::File f(TEST_FILE_PATH_C("excessive_alloc.aif")); - CPPUNIT_ASSERT(!f.isValid()); + CPPUNIT_ASSERT(f.isValid()); } }; diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index fd0c04f7..c0717398 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ class TestWAV : public CppUnit::TestFixture CPPUNIT_TEST(testDuplicateTags); CPPUNIT_TEST(testFuzzedFile1); CPPUNIT_TEST(testFuzzedFile2); + CPPUNIT_TEST(testFileWithGarbageAppended); CPPUNIT_TEST(testStripAndProperties); CPPUNIT_TEST(testPCMWithFactChunk); CPPUNIT_TEST_SUITE_END(); @@ -101,7 +103,7 @@ public: void testZeroSizeDataChunk() { RIFF::WAV::File f(TEST_FILE_PATH_C("zero-size-chunk.wav")); - CPPUNIT_ASSERT(!f.isValid()); + CPPUNIT_ASSERT(f.isValid()); } void testID3v2Tag() @@ -262,7 +264,17 @@ public: void testFuzzedFile1() { RIFF::WAV::File f1(TEST_FILE_PATH_C("infloop.wav")); - CPPUNIT_ASSERT(!f1.isValid()); + CPPUNIT_ASSERT(f1.isValid()); + // The file has problems: + // Chunk 'ISTt' has invalid size (larger than the file size). + // Its properties can nevertheless be read. + RIFF::WAV::Properties* properties = f1.audioProperties(); + CPPUNIT_ASSERT_EQUAL(1, properties->channels()); + CPPUNIT_ASSERT_EQUAL(88, properties->bitrate()); + CPPUNIT_ASSERT_EQUAL(8, properties->bitsPerSample()); + CPPUNIT_ASSERT_EQUAL(11025, properties->sampleRate()); + CPPUNIT_ASSERT(!f1.hasInfoTag()); + CPPUNIT_ASSERT(!f1.hasID3v2Tag()); } void testFuzzedFile2() @@ -271,6 +283,36 @@ public: CPPUNIT_ASSERT(f2.isValid()); } + void testFileWithGarbageAppended() + { + ScopedFileCopy copy("empty", ".wav"); + ByteVector contentsBeforeModification; + { + FileStream stream(copy.fileName().c_str()); + stream.seek(0, IOStream::End); + const char garbage[] = "12345678"; + stream.writeBlock(ByteVector(garbage, sizeof(garbage) - 1)); + stream.seek(0); + contentsBeforeModification = stream.readBlock(stream.length()); + } + { + RIFF::WAV::File f(copy.fileName().c_str()); + CPPUNIT_ASSERT(f.isValid()); + f.ID3v2Tag()->setTitle("ID3v2 Title"); + f.InfoTag()->setTitle("INFO Title"); + CPPUNIT_ASSERT(f.save()); + } + { + RIFF::WAV::File f(copy.fileName().c_str()); + f.strip(); + } + { + FileStream stream(copy.fileName().c_str()); + ByteVector contentsAfterModification = stream.readBlock(stream.length()); + CPPUNIT_ASSERT_EQUAL(contentsBeforeModification, contentsAfterModification); + } + } + void testStripAndProperties() { ScopedFileCopy copy("empty", ".wav");