Bug 1324209 - Safely iterate over mIntersectionObservers in nsDocument::NotifyIntersectionObservers. r?mstange
MozReview-Commit-ID: KxKbhbaS2gA
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -202,17 +202,19 @@ DOMIntersectionObserver::Disconnect()
mConnected = false;
for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
Element* target = iter.Get()->GetKey();
target->UnregisterIntersectionObserver(this);
}
mObservationTargets.Clear();
if (mOwner) {
nsIDocument* document = mOwner->GetExtantDoc();
- document->RemoveIntersectionObserver(this);
+ if (document) {
+ document->RemoveIntersectionObserver(this);
+ }
}
}
void
DOMIntersectionObserver::TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal)
{
aRetVal.SwapElements(mQueuedEntries);
mQueuedEntries.Clear();
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1324209.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script type="application/javascript">
+
+function crash() {
+ var target1 = document.getElementById("target1");
+ var target2 = document.getElementById("target2");
+ var observer1 = new IntersectionObserver(function (entries) {
+ console.log(entries);
+ observer1.disconnect();
+ observer2.disconnect();
+ });
+ var observer2 = new IntersectionObserver(function (entries) {
+ console.log(entries);
+ });
+ observer1.observe(target1);
+ observer2.observe(target2);
+}
+
+</script>
+</head>
+<body onload="crash()">
+ <div id="target1" style="background: red; width: 50px; height: 50px"></div>
+ <div id="target2" style="background: green; width: 50px; height: 50px"></div>
+</body>
+</html>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -203,8 +203,9 @@ load 1158412.html
load 1181619.html
load structured_clone_container_throws.html
HTTP(..) load xhr_abortinprogress.html
load xhr_empty_datauri.html
load xhr_html_nullresponse.html
load 1230422.html
load 1251361.html
load 1304437.html
+pref(dom.IntersectionObserver.enabled,true) load 1324209.html
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12390,17 +12390,18 @@ nsDocument::ScheduleIntersectionObserver
nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this,
&nsDocument::NotifyIntersectionObservers);
NS_DispatchToCurrentThread(notification);
}
void
nsDocument::NotifyIntersectionObservers()
{
- for (const auto& observer : mIntersectionObservers) {
+ nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers);
+ for (const auto& observer : observers) {
observer->Notify();
}
}
static bool
NotifyLayerManagerRecreatedCallback(nsIDocument* aDocument, void* aData)
{
aDocument->NotifyLayerManagerRecreated();