diff --git a/taglib/mp4/mp4file.cpp b/taglib/mp4/mp4file.cpp index 566a5e32..d0a6c4c6 100644 --- a/taglib/mp4/mp4file.cpp +++ b/taglib/mp4/mp4file.cpp @@ -55,8 +55,7 @@ public: FilePrivate() : tag(0), atoms(0), - properties(0), - hasMP4Tag(false) {} + properties(0) {} ~FilePrivate() { @@ -68,8 +67,6 @@ public: MP4::Tag *tag; MP4::Atoms *atoms; MP4::Properties *properties; - - bool hasMP4Tag; }; MP4::File::File(FileName file, bool readProperties, AudioProperties::ReadStyle) : @@ -138,10 +135,6 @@ MP4::File::read(bool readProperties) return; } - if(d->atoms->find("moov", "udta", "meta", "ilst")) { - d->hasMP4Tag = true; - } - d->tag = new Tag(this, d->atoms); if(readProperties) { d->properties = new Properties(this, d->atoms); @@ -161,16 +154,11 @@ MP4::File::save() return false; } - const bool success = d->tag->save(); - if(success) { - d->hasMP4Tag = true; - } - - return success; + return d->tag->save(); } bool MP4::File::hasMP4Tag() const { - return d->hasMP4Tag; + return (d->atoms->find("moov", "udta", "meta", "ilst") != 0); } diff --git a/taglib/mp4/mp4file.h b/taglib/mp4/mp4file.h index 40fcde78..3840bd02 100644 --- a/taglib/mp4/mp4file.h +++ b/taglib/mp4/mp4file.h @@ -111,9 +111,6 @@ namespace TagLib { * Save the file. * * This returns true if the save was successful. - * - * \warning In the current implementation, it's dangerous to call save() - * repeatedly. At worst it will corrupt the file. */ bool save(); diff --git a/taglib/mp4/mp4tag.cpp b/taglib/mp4/mp4tag.cpp index 84219196..384a4548 100644 --- a/taglib/mp4/mp4tag.cpp +++ b/taglib/mp4/mp4tag.cpp @@ -629,6 +629,11 @@ MP4::Tag::saveNew(ByteVector data) updateParents(path, data.size()); updateOffsets(data.size(), offset); + + // Insert the newly created atoms into the tree to keep it up-to-date. + + d->file->seek(offset); + path.back()->children.prepend(new Atom(d->file)); } void diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp index 58dbae42..10b1e1fc 100644 --- a/tests/test_mp4.cpp +++ b/tests/test_mp4.cpp @@ -30,6 +30,7 @@ class TestMP4 : public CppUnit::TestFixture CPPUNIT_TEST(testCovrRead2); CPPUNIT_TEST(testProperties); CPPUNIT_TEST(testFuzzedFile); + CPPUNIT_TEST(testRepeatedSave); CPPUNIT_TEST_SUITE_END(); public: @@ -344,6 +345,17 @@ public: CPPUNIT_ASSERT(f.isValid()); } + void testRepeatedSave() + { + ScopedFileCopy copy("no-tags", ".m4a"); + + MP4::File f(copy.fileName().c_str()); + f.tag()->setTitle("0123456789"); + f.save(); + f.save(); + CPPUNIT_ASSERT_EQUAL(2862L, f.find("0123456789")); + CPPUNIT_ASSERT_EQUAL(-1L, f.find("0123456789", 2863)); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);