diff --git a/NEWS b/NEWS index 61aa6cfe..3d16bd81 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,7 @@ TagLib 1.10 (??? ??, 2015) * New API for the audio length in milliseconds. * Marked FLAC::File::streamInfoData() deprecated. It returns an empty ByteVector. * Marked FLAC::File::streamLength() deprecated. It returns zero. + * Fixed possible file corruptions when adding an ID3v1 tag to FLAC files. * Many smaller bug fixes and performance improvements. TagLib 1.9.1 (Oct 8, 2013) diff --git a/taglib/flac/flacfile.cpp b/taglib/flac/flacfile.cpp index dbf0d767..4d2d69e6 100644 --- a/taglib/flac/flacfile.cpp +++ b/taglib/flac/flacfile.cpp @@ -258,8 +258,16 @@ bool FLAC::File::save() } if(ID3v1Tag()) { - seek(-128, End); + if(d->hasID3v1) { + seek(d->ID3v1Location); + } + else { + seek(0, End); + d->ID3v1Location = tell(); + } + writeBlock(ID3v1Tag()->render()); + d->hasID3v1 = true; } return true; diff --git a/tests/test_flac.cpp b/tests/test_flac.cpp index dd09b3ea..54104cc5 100644 --- a/tests/test_flac.cpp +++ b/tests/test_flac.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "utils.h" @@ -27,6 +28,7 @@ class TestFLAC : public CppUnit::TestFixture CPPUNIT_TEST(testInvalid); CPPUNIT_TEST(testAudioProperties); CPPUNIT_TEST(testZeroSizedPadding); + CPPUNIT_TEST(testSaveID3v1); CPPUNIT_TEST_SUITE_END(); public: @@ -283,6 +285,29 @@ public: CPPUNIT_ASSERT(f.isValid()); } + void testSaveID3v1() + { + ScopedFileCopy copy("no-tags", ".flac"); + + ByteVector audioStream; + { + FLAC::File f(copy.fileName().c_str()); + CPPUNIT_ASSERT(!f.hasID3v1Tag()); + CPPUNIT_ASSERT_EQUAL((long)4692, f.length()); + + f.seek(0x0100); + audioStream = f.readBlock(4436); + + f.ID3v1Tag(true)->setTitle("01234 56789 ABCDE FGHIJ"); + f.save(); + CPPUNIT_ASSERT(f.hasID3v1Tag()); + CPPUNIT_ASSERT_EQUAL((long)4820, f.length()); + + f.seek(0x0100); + CPPUNIT_ASSERT_EQUAL(audioStream, f.readBlock(4436)); + } + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestFLAC);