Bug 1258576 - Part 1: nsContentIterator should give up to find next/previous node if it reached the root node unexpectedly. r=smaug, a=ritu
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 31 Mar 2016 15:00:50 +0900
changeset 323846 ce029b692d558f9d1c8e8d7e9f15adf83101c91f
parent 323845 f1c193f20df7ae8c91068d12cd04eaa55ad46d50
child 323847 108c0f85a2453962485973e9b3f31c48eea38086
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, ritu
bugs1258576
milestone47.0a2
Bug 1258576 - Part 1: nsContentIterator should give up to find next/previous node if it reached the root node unexpectedly. r=smaug, a=ritu nsContentIterator isn't designed as working fine with a tree whose some nodes are being removed. In such case, NextNode() and PrevNode() meets orphan node (i.e., a node whose parent is nullptr). Then, nsContentIterator should mark it as "done". However, it should keep crashing if it's debug build for detecting bugs explicitly. MozReview-Commit-ID: 81ZQgoHD67T
dom/base/nsContentIterator.cpp
--- a/dom/base/nsContentIterator.cpp
+++ b/dom/base/nsContentIterator.cpp
@@ -769,17 +769,21 @@ nsContentIterator::NextNode(nsINode* aNo
     }
 
     // else next sibling is next
     return GetNextSibling(node, aIndexes);
   }
 
   // post-order
   nsINode* parent = node->GetParentNode();
-  NS_WARN_IF(!parent);
+  if (NS_WARN_IF(!parent)) {
+    MOZ_ASSERT(parent, "The node is the root node but not the last node");
+    mIsDone = true;
+    return node;
+  }
   nsIContent* sibling = nullptr;
   int32_t indx = 0;
 
   // get the cached index
   NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                "ContentIterator stack underflow");
   if (aIndexes && !aIndexes->IsEmpty()) {
     // use the last entry on the Indexes array for the current index
@@ -834,17 +838,21 @@ nsContentIterator::NextNode(nsINode* aNo
 nsINode*
 nsContentIterator::PrevNode(nsINode* aNode, nsTArray<int32_t>* aIndexes)
 {
   nsINode* node = aNode;
 
   // if we are a Pre-order iterator, use pre-order
   if (mPre) {
     nsINode* parent = node->GetParentNode();
-    NS_WARN_IF(!parent);
+    if (NS_WARN_IF(!parent)) {
+      MOZ_ASSERT(parent, "The node is the root node but not the first node");
+      mIsDone = true;
+      return aNode;
+    }
     nsIContent* sibling = nullptr;
     int32_t indx = 0;
 
     // get the cached index
     NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                  "ContentIterator stack underflow");
     if (aIndexes && !aIndexes->IsEmpty()) {
       // use the last entry on the Indexes array for the current index