From 52b4f2a40a045693f1cb54085f2b60f2cd97e210 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 29 Jul 2025 23:34:58 +0200 Subject: [PATCH] LibWeb: Don't visit registered document observers from Document `DocumentObserver` register itself in Document` from constructor and unregister itself from `finalize()`. The problem is that `finalize()` won't be invoked for as long as `DocumentObserver` is visited by `Document`. By not visiting registered observers from `Document` we move this responsibility to object that allocated observer, which is always exactly what we want, e.g. once `SVGUseElement` that uses observer is gone, observer won't be visited anymore which will lead to `finalize()` being called. --- Libraries/LibWeb/DOM/Document.cpp | 1 - Libraries/LibWeb/DOM/Document.h | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 40287ac8d9a..39f88197771 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -581,7 +581,6 @@ void Document::visit_edges(Cell::Visitor& visitor) visitor.visit(m_scripts_to_execute_in_order_as_soon_as_possible); visitor.visit(m_scripts_to_execute_as_soon_as_possible); visitor.visit(m_node_iterators); - visitor.visit(m_document_observers); visitor.visit(m_document_observers_being_notified); visitor.visit(m_pending_scroll_event_targets); visitor.visit(m_pending_scrollend_event_targets); diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index 7e1844fc9cd..b72164e54a7 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -1081,7 +1081,9 @@ private: HashTable> m_node_iterators; - HashTable> m_document_observers; + // Document should not visit DocumentObserver to avoid leaks. + // It's responsibility of object that requires DocumentObserver to keep it alive. + HashTable> m_document_observers; Vector> m_document_observers_being_notified; // https://html.spec.whatwg.org/multipage/dom.html#is-initial-about:blank