From 2185b47d5f1dc1266e05730bf3ba59a788f3a443 Mon Sep 17 00:00:00 2001 From: Anthony Brandon Date: Wed, 24 Jun 2026 17:19:46 +0200 Subject: [PATCH] [Matroska] Clear size listeners before adding Each time save is called registerSizeListener will add new size listeners. If save is called multiple times this causes the same delta being add/subtracted multiple times, resulting in incorrect element sizes. This can be observed in TestMatroska::testRepeatedSave. Although the test passes, some sizes are incorrect resulting in the following messages being printed during the test: TagLib: Failed to read VINT size TagLib: Failed to parse EMBL ElementID Signed-off-by: Anthony Brandon --- taglib/matroska/matroskaelement.cpp | 5 +++++ taglib/matroska/matroskaelement.h | 1 + taglib/matroska/matroskafile.cpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/taglib/matroska/matroskaelement.cpp b/taglib/matroska/matroskaelement.cpp index 27babd50..e57b262b 100644 --- a/taglib/matroska/matroskaelement.cpp +++ b/taglib/matroska/matroskaelement.cpp @@ -101,6 +101,11 @@ Matroska::Element::ID Matroska::Element::id() const return e->id; } +void Matroska::Element::clearSizeListeners() +{ + e->sizeListeners.clear(); +} + void Matroska::Element::addSizeListener(Element *element) { e->sizeListeners.append(element); diff --git a/taglib/matroska/matroskaelement.h b/taglib/matroska/matroskaelement.h index 881750d7..e70fcc6f 100644 --- a/taglib/matroska/matroskaelement.h +++ b/taglib/matroska/matroskaelement.h @@ -53,6 +53,7 @@ namespace TagLib { void setData(const ByteVector &data); const ByteVector &data() const; virtual void write(TagLib::File &file); + void clearSizeListeners(); void addSizeListener(Element *element); void addSizeListeners(const List &elements); bool emitSizeChanged(offset_t delta); diff --git a/taglib/matroska/matroskafile.cpp b/taglib/matroska/matroskafile.cpp index 920a50cd..627f0810 100644 --- a/taglib/matroska/matroskafile.cpp +++ b/taglib/matroska/matroskafile.cpp @@ -595,6 +595,7 @@ bool Matroska::File::save(WriteStyle writeStyle) // Set up listeners, add seek head and segment length to the end for(auto it = renderList.begin(); it != renderList.end(); ++it) { + (*it)->clearSizeListeners(); for(auto it2 = std::next(it); it2 != renderList.end(); ++it2) (*it)->addSizeListener(*it2); if(d->cues) @@ -605,6 +606,7 @@ bool Matroska::File::save(WriteStyle writeStyle) } if(d->cues) { renderList.append(d->cues.get()); + d->cues->clearSizeListeners(); d->cues->addSizeListeners(renderList); if(d->seekHead) { d->cues->addSizeListener(d->seekHead.get()); @@ -613,9 +615,11 @@ bool Matroska::File::save(WriteStyle writeStyle) } if(d->seekHead) { renderList.append(d->seekHead.get()); + d->seekHead->clearSizeListeners(); d->seekHead->addSizeListeners(renderList); d->seekHead->addSizeListener(d->segment.get()); } + d->segment->clearSizeListeners(); d->segment->addSizeListeners(renderList); renderList.append(d->segment.get());