Bug 1375131 - Part 1. Store ranges before using on loop. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 23 Jun 2017 16:45:26 +0900
changeset 599486 812f3d9b1da726e6ac881d386c923b8093b92200
parent 599416 7455c74d833a9db4e02be17eda14588c7ef0de76
child 599487 bb4dc90930f9776acbc3c844c575a8a419aa0131
push id65545
push userm_kato@ga2.so-net.ne.jp
push dateFri, 23 Jun 2017 07:53:00 +0000
reviewersmasayuki
bugs1375131
milestone56.0a1
Bug 1375131 - Part 1. Store ranges before using on loop. r?masayuki This crash occurs that range is nullptr. DeleteNonTableElements will update selection and range, so we shouldn't use range count before modifying selection. So we should save range data for loop. MozReview-Commit-ID: C9c4TZqRvUc
editor/libeditor/EditorUtils.h
editor/libeditor/HTMLEditRules.cpp
--- a/editor/libeditor/EditorUtils.h
+++ b/editor/libeditor/EditorUtils.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef mozilla_EditorUtils_h
 #define mozilla_EditorUtils_h
 
+#include "mozilla/dom/Selection.h"
 #include "mozilla/EditorBase.h"
 #include "mozilla/GuardObjects.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsIDOMNode.h"
 #include "nsIEditor.h"
 #include "nscore.h"
 
@@ -21,20 +22,16 @@ class nsIDOMDocument;
 class nsIDOMEvent;
 class nsISimpleEnumerator;
 class nsITransferable;
 class nsRange;
 
 namespace mozilla {
 template <class T> class OwningNonNull;
 
-namespace dom {
-class Selection;
-} // namespace dom
-
 /***************************************************************************
  * EditActionResult is useful to return multiple results of an editor
  * action handler without out params.
  * Note that when you return an anonymous instance from a method, you should
  * use EditActionIgnored(), EditActionHandled() or EditActionCanceled() for
  * easier to read.  In other words, EditActionResult should be used when
  * declaring return type of a method, being an argument or defined as a local
  * variable.
@@ -317,16 +314,33 @@ public:
     }
   }
 
 protected:
   EditorBase* mEditorBase;
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+class MOZ_STACK_CLASS AutoRangeArray final
+{
+public:
+  AutoRangeArray(dom::Selection* aSelection)
+  {
+    if (!aSelection) {
+      return;
+    }
+    uint32_t rangeCount = aSelection->RangeCount();
+    for (uint32_t i = 0; i < rangeCount; i++) {
+      mRanges.AppendElement(*aSelection->GetRangeAt(i));
+    }
+  }
+
+  AutoTArray<mozilla::OwningNonNull<nsRange>, 8> mRanges;
+};
+
 /******************************************************************************
  * some helper classes for iterating the dom tree
  *****************************************************************************/
 
 class BoolDomIterFunctor
 {
 public:
   virtual bool operator()(nsINode* aNode) const = 0;
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -2447,20 +2447,18 @@ HTMLEditRules::WillDeleteSelection(Selec
           NS_ENSURE_SUCCESS(rv, rv);
           return NS_OK;
         }
 
         // Else blocks not same type, or not siblings.  Delete everything
         // except table elements.
         join = true;
 
-        uint32_t rangeCount = aSelection->RangeCount();
-        for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
-          OwningNonNull<nsRange> range = *aSelection->GetRangeAt(rangeIdx);
-
+        AutoRangeArray arrayOfRanges(aSelection);
+        for (auto& range : arrayOfRanges.mRanges) {
           // Build a list of nodes in the range
           nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
           TrivialFunctor functor;
           DOMSubtreeIterator iter;
           nsresult rv = iter.Init(*range);
           NS_ENSURE_SUCCESS(rv, rv);
           iter.AppendList(functor, arrayOfNodes);