Bug 1258576 part.1 nsContentIterator should give up to find next/previous node if it reached the root node unexpectedly draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 31 Mar 2016 15:00:50 +0900
changeset 346227 ff838cbddab667848687b9c59c11b1b380234370
parent 346218 1a1b7c3daaa2cdad428ebedde5aa42ba51b497f6
child 517368 4083647d9d8de9b195c42d494083182acc62a36e
push id14292
push usermasayuki@d-toybox.com
push dateThu, 31 Mar 2016 10:16:52 +0000
bugs1258576
milestone48.0a1
Bug 1258576 part.1 nsContentIterator should give up to find next/previous node if it reached the root node unexpectedly 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