https://bugs.webkit.org/show_bug.cgi?id=119124
Reviewed by Sam Weinig.
Merge https://chromium.googlesource.com/chromium/blink/+/
b6afb927695b3acf2c75c25f05e99682660993e2
No new tests since I could not reproduce the crash with the test attached in the Blink change.
The bug was caused by Node::unregisterMutationObserver removing the MutationObserverRegistration
that holds the last ref to the node. Avoid that by explicitly allocating a local RefPtr to the node
in MutationObserverRegistration::unregister. Also rename it to unregisterAndDelete to clarify
the semantics and make it a static member function to be even safer.
* dom/MutationObserver.cpp:
(WebCore::MutationObserver::disconnect):
* dom/MutationObserverRegistration.cpp:
(WebCore::MutationObserverRegistration::unregisterAndDelete):
* dom/MutationObserverRegistration.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153447
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2013-07-26 Ryosuke Niwa <rniwa@webkit.org>
+
+ Fix crash due to unexpected Node deletion during MutationObserver registration book-keeping
+ https://bugs.webkit.org/show_bug.cgi?id=119124
+
+ Reviewed by Sam Weinig.
+
+ Merge https://chromium.googlesource.com/chromium/blink/+/b6afb927695b3acf2c75c25f05e99682660993e2
+
+ No new tests since I could not reproduce the crash with the test attached in the Blink change.
+
+ The bug was caused by Node::unregisterMutationObserver removing the MutationObserverRegistration
+ that holds the last ref to the node. Avoid that by explicitly allocating a local RefPtr to the node
+ in MutationObserverRegistration::unregister. Also rename it to unregisterAndDelete to clarify
+ the semantics and make it a static member function to be even safer.
+
+ * dom/MutationObserver.cpp:
+ (WebCore::MutationObserver::disconnect):
+ * dom/MutationObserverRegistration.cpp:
+ (WebCore::MutationObserverRegistration::unregisterAndDelete):
+ * dom/MutationObserverRegistration.h:
+
2013-07-29 Alex Christensen <achristensen@apple.com>
Moved GLTransportSurface.h and .cpp out of efl-specific directory.
m_records.clear();
HashSet<MutationObserverRegistration*> registrations(m_registrations);
for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
- (*iter)->unregister();
+ MutationObserverRegistration::unregisterAndDelete(*iter);
}
void MutationObserver::observationStarted(MutationObserverRegistration* registration)
m_registrationNodeKeepAlive = 0; // Balanced in observeSubtreeNodeWillDetach.
}
-void MutationObserverRegistration::unregister()
+void MutationObserverRegistration::unregisterAndDelete(MutationObserverRegistration* registry)
{
- m_registrationNode->unregisterMutationObserver(this);
- // The above line will cause this object to be deleted, so don't do any more in this function.
+ RefPtr<Node> registrationNode(registry->m_registrationNode);
+ registrationNode->unregisterMutationObserver(registry);
+ // The above line will cause registry to be deleted, so don't do any more in this function.
}
bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
void observedSubtreeNodeWillDetach(Node*);
void clearTransientRegistrations();
bool hasTransientRegistrations() const { return m_transientRegistrationNodes && !m_transientRegistrationNodes->isEmpty(); }
- void unregister();
+ static void unregisterAndDelete(MutationObserverRegistration*);
bool shouldReceiveMutationFrom(Node*, MutationObserver::MutationType, const QualifiedName* attributeName) const;
bool isSubtree() const { return m_options & MutationObserver::Subtree; }