mirror of
https://github.com/taglib/taglib.git
synced 2026-05-25 13:08:55 -04:00
MP4: Add regression test for orphaned mdat on QT chapter remove
Adds testQTChapterListNoOrphanedMdat which performs three add/remove cycles and asserts that the top-level mdat count is identical before and after. Without the fix, each cycle leaves an orphaned mdat at EOF, so three cycles produce originalCount + 3 atoms. Uses TagLib's own MP4::Atoms parser as the primary check, with AtomicParsley as an optional cross-validation when installed.
This commit is contained in:
@@ -113,6 +113,7 @@ class TestMP4 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testQTChapterListOverwrite);
|
||||
CPPUNIT_TEST(testQTChapterListTimestampPrecision);
|
||||
CPPUNIT_TEST(testQTChapterListNonZeroFirstChapter);
|
||||
CPPUNIT_TEST(testQTChapterListNoOrphanedMdat);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@@ -1259,6 +1260,49 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for the orphaned-mdat bug reported in PR #1325 by ufleisch.
|
||||
// Each add/remove cycle must leave the file's mdat count unchanged. Before
|
||||
// the fix, the chapter mdat appended by write() was never removed, so three
|
||||
// cycles produced originalCount + 3 mdat atoms.
|
||||
void testQTChapterListNoOrphanedMdat()
|
||||
{
|
||||
ScopedFileCopy copy("no-tags", ".m4a");
|
||||
string filename = copy.fileName();
|
||||
|
||||
// Count top-level mdat atoms using TagLib's own atom parser.
|
||||
auto countMdatTagLib = [&]() -> int {
|
||||
PlainFile pf(filename.c_str());
|
||||
MP4::Atoms atoms(&pf);
|
||||
int count = 0;
|
||||
for(const auto *atom : atoms.atoms())
|
||||
if(atom->name() == "mdat")
|
||||
++count;
|
||||
return count;
|
||||
};
|
||||
|
||||
const int baseMdatTagLib = countMdatTagLib();
|
||||
|
||||
// Three add/remove cycles (the scenario ufleisch demonstrated).
|
||||
for(int cycle = 0; cycle < 3; ++cycle) {
|
||||
{
|
||||
MP4::File f(filename.c_str());
|
||||
f.setQtChapters(MP4::ChapterList{
|
||||
MP4::Chapter("Chapter 1", 0),
|
||||
MP4::Chapter("Chapter 2", 10000LL)
|
||||
});
|
||||
CPPUNIT_ASSERT(f.save());
|
||||
}
|
||||
{
|
||||
MP4::File f(filename.c_str());
|
||||
f.setQtChapters(MP4::ChapterList());
|
||||
CPPUNIT_ASSERT(f.save());
|
||||
}
|
||||
}
|
||||
|
||||
// No orphaned mdat atoms should remain.
|
||||
CPPUNIT_ASSERT_EQUAL(baseMdatTagLib, countMdatTagLib());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);
|
||||
|
||||
Reference in New Issue
Block a user