Bug 1315837 - Crash in mozilla::dom::Element::UpdateIntersectionObservation. r=mrbkap
authorTobias Schneider <tschneider@mozilla.com>
Wed, 23 Nov 2016 13:14:00 -0500
changeset 324134 bf9f20dbe8d822c3854bf9038e56313349df559b
parent 324133 70a5d943ef16592b3d40e2f265aa59fa0e23f884
child 324135 968fe7fa5d930f46e8b2caf2e24e316beed02f5d
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmrbkap
bugs1315837
milestone53.0a1
Bug 1315837 - Crash in mozilla::dom::Element::UpdateIntersectionObservation. r=mrbkap
dom/base/DOMIntersectionObserver.cpp
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -165,21 +165,22 @@ DOMIntersectionObserver::Unobserve(Eleme
 }
 
 bool
 DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
 {
     if (!mObservationTargets.Contains(&aTarget)) {
         return false;
     }
-    if (mObservationTargets.Count() == 1) {
+
+    mObservationTargets.RemoveEntry(&aTarget);
+    if (mObservationTargets.Count() == 0) {
         Disconnect();
         return false;
     }
-    mObservationTargets.RemoveEntry(&aTarget);
     return true;
 }
 
 void
 DOMIntersectionObserver::Connect()
 {
   if (mConnected) {
     return;
@@ -190,26 +191,27 @@ DOMIntersectionObserver::Connect()
 }
 
 void
 DOMIntersectionObserver::Disconnect()
 {
   if (!mConnected) {
     return;
   }
+
+  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);
   }
-  mConnected = false;
 }
 
 void
 DOMIntersectionObserver::TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal)
 {
   aRetVal.SwapElements(mQueuedEntries);
   mQueuedEntries.Clear();
 }
@@ -273,17 +275,20 @@ DOMIntersectionObserver::Update(nsIDocum
     }
   } else {
     nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
     if (presShell) {
       rootFrame = presShell->GetRootScrollFrame();
       if (rootFrame) {
         nsPresContext* presContext = rootFrame->PresContext();
         while (!presContext->IsRootContentDocument()) {
-          presContext = rootFrame->PresContext()->GetParentPresContext();
+          presContext = presContext->GetParentPresContext();
+          if (!presContext) {
+            break;
+          }
           rootFrame = presContext->PresShell()->GetRootScrollFrame();
         }
         root = rootFrame->GetContent()->AsElement();
         nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
         rootRect = scrollFrame->GetScrollPortRect();
       }
     }
   }