Backed out changeset 9843839bf1df (bug 1406482) for mozilla::EditorBase::InsertTextImpl crashes
authorPhil Ringnalda <philringnalda@gmail.com>
Mon, 09 Oct 2017 21:32:12 -0700
changeset 385286 e9fdabc86073de7f425b0a42ad8899c298bca5d3
parent 385285 ec0c2767cf57ed606e9bed54a15d6bdadae12579
child 385287 56fffcd3581f39be3f3af1ff62d77e51816a7db6
push id32650
push userarchaeopteryx@coole-files.de
push dateTue, 10 Oct 2017 09:13:16 +0000
treeherdermozilla-central@77a4c52e9987 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1406482
milestone58.0a1
backs out9843839bf1df069f86acb555bbbe44af78b99e9c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 9843839bf1df (bug 1406482) for mozilla::EditorBase::InsertTextImpl crashes MozReview-Commit-ID: J7rX4lX2lxM
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/WSRunObject.cpp
editor/libeditor/WSRunObject.h
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -2476,17 +2476,16 @@ EditorBase::FindBetterInsertionPoint(nsC
       return;
     }
   }
 }
 
 nsresult
 EditorBase::InsertTextImpl(const nsAString& aStringToInsert,
                            nsCOMPtr<nsINode>* aInOutNode,
-                           nsIContent* aChildAtOffset,
                            int32_t* aInOutOffset,
                            nsIDocument* aDoc)
 {
   // NOTE: caller *must* have already used AutoTransactionsConserveSelection
   // stack-based class to turn off txn selection updating.  Caller also turned
   // on rules sniffing if desired.
 
   NS_ENSURE_TRUE(aInOutNode && *aInOutNode && aInOutOffset && aDoc,
@@ -2508,25 +2507,24 @@ EditorBase::InsertTextImpl(const nsAStri
 
   // In some cases, the node may be the anonymous div elemnt or a mozBR
   // element.  Let's try to look for better insertion point in the nearest
   // text node if there is.
   FindBetterInsertionPoint(node, offset);
 
   // If a neighboring text node already exists, use that
   if (!node->IsNodeOfType(nsINode::eTEXT)) {
-    if (offset && aChildAtOffset &&
-        aChildAtOffset->GetPreviousSibling() &&
-        aChildAtOffset->GetPreviousSibling()->IsNodeOfType(nsINode::eTEXT)) {
-      node = aChildAtOffset->GetPreviousSibling();
+    nsIContent* child = node->GetChildAt(offset);
+    if (offset && child && child->GetPreviousSibling() &&
+        child->GetPreviousSibling()->IsNodeOfType(nsINode::eTEXT)) {
+      node = child->GetPreviousSibling();
       offset = node->Length();
     } else if (offset < static_cast<int32_t>(node->Length()) &&
-               aChildAtOffset &&
-               aChildAtOffset->IsNodeOfType(nsINode::eTEXT)) {
-      node = aChildAtOffset;
+               child && child->IsNodeOfType(nsINode::eTEXT)) {
+      node = child;
       offset = 0;
     }
   }
 
   if (ShouldHandleIMEComposition()) {
     CheckedInt<int32_t> newOffset;
     if (!node->IsNodeOfType(nsINode::eTEXT)) {
       // create a text node
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -282,17 +282,16 @@ public:
   // nsIEditor methods
   NS_DECL_NSIEDITOR
 
 public:
   virtual bool IsModifiableNode(nsINode* aNode);
 
   virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
                                   nsCOMPtr<nsINode>* aInOutNode,
-                                  nsIContent* aChildAtOffset,
                                   int32_t* aInOutOffset,
                                   nsIDocument* aDoc);
   nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
                                       Text& aTextNode, int32_t aOffset,
                                       bool aSuppressIME = false);
 
   nsresult SetTextImpl(Selection& aSelection,
                        const nsAString& aString,
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1291,17 +1291,16 @@ HTMLEditRules::WillInsertText(EditAction
   // for every property that is set, insert a new inline style node
   nsresult rv = CreateStyleForInsertText(*aSelection, *doc);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // get the (collapsed) selection location
   NS_ENSURE_STATE(mHTMLEditor);
   NS_ENSURE_STATE(aSelection->GetRangeAt(0));
   nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartContainer();
-  nsIContent* selChild = aSelection->GetRangeAt(0)->GetChildAtStartOffset();
   int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset();
   NS_ENSURE_STATE(selNode);
 
   // dont put text in places that can't have it
   NS_ENSURE_STATE(mHTMLEditor);
   if (!EditorBase::IsTextNode(selNode) &&
       (!mHTMLEditor || !mHTMLEditor->CanContainTag(*selNode,
                                                    *nsGkAtoms::textTagName))) {
@@ -1316,24 +1315,23 @@ HTMLEditRules::WillInsertText(EditAction
     // the insertion point.
     int32_t IMESelectionOffset =
       mHTMLEditor->GetIMESelectionStartOffsetIn(selNode);
     if (IMESelectionOffset >= 0) {
       selOffset = IMESelectionOffset;
     }
     if (inString->IsEmpty()) {
       rv = mHTMLEditor->InsertTextImpl(*inString, address_of(selNode),
-                                       selChild, &selOffset, doc);
+                                       &selOffset, doc);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else {
       WSRunObject wsObj(mHTMLEditor, selNode, selOffset);
-      rv = wsObj.InsertText(*inString, address_of(selNode), selChild,
-                            &selOffset, doc);
+      rv = wsObj.InsertText(*inString, address_of(selNode), &selOffset, doc);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
   // aAction == kInsertText
   else {
     // find where we are
@@ -1395,17 +1393,17 @@ HTMLEditRules::WillInsertText(EditAction
             nsCOMPtr<Element> br =
               mHTMLEditor->CreateBRImpl(address_of(curNode), &curOffset,
                                         nsIEditor::eNone);
             NS_ENSURE_STATE(br);
             pos++;
           } else {
             NS_ENSURE_STATE(mHTMLEditor);
             rv = mHTMLEditor->InsertTextImpl(subStr, address_of(curNode),
-                                             selChild, &curOffset, doc);
+                                             &curOffset, doc);
             NS_ENSURE_SUCCESS(rv, rv);
           }
         }
       } else {
         NS_NAMED_LITERAL_STRING(tabStr, "\t");
         NS_NAMED_LITERAL_STRING(spacesStr, "    ");
         char specialChars[] = {TAB, nsCRT::LF, 0};
         while (unicodeBuf && pos != -1 &&
@@ -1427,31 +1425,29 @@ HTMLEditRules::WillInsertText(EditAction
 
           nsDependentSubstring subStr(tString, oldPos, subStrLen);
           NS_ENSURE_STATE(mHTMLEditor);
           WSRunObject wsObj(mHTMLEditor, curNode, curOffset);
 
           // is it a tab?
           if (subStr.Equals(tabStr)) {
             rv =
-              wsObj.InsertText(spacesStr, address_of(curNode), selChild,
-                               &curOffset, doc);
+              wsObj.InsertText(spacesStr, address_of(curNode), &curOffset, doc);
             NS_ENSURE_SUCCESS(rv, rv);
             pos++;
           }
           // is it a return?
           else if (subStr.Equals(newlineStr)) {
             nsCOMPtr<Element> br = wsObj.InsertBreak(address_of(curNode),
                                                      &curOffset,
                                                      nsIEditor::eNone);
             NS_ENSURE_TRUE(br, NS_ERROR_FAILURE);
             pos++;
           } else {
-            rv = wsObj.InsertText(subStr, address_of(curNode), selChild,
-                                  &curOffset, doc);
+            rv = wsObj.InsertText(subStr, address_of(curNode), &curOffset, doc);
             NS_ENSURE_SUCCESS(rv, rv);
           }
         }
       }
     }
     aSelection->SetInterlinePosition(false);
     if (curNode) aSelection->Collapse(curNode, curOffset);
     // manually update the doc changed range so that AfterEdit will clean up
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3113,27 +3113,26 @@ HTMLEditor::DeleteText(nsGenericDOMDataN
   }
 
   return EditorBase::DeleteText(aCharData, aOffset, aLength);
 }
 
 nsresult
 HTMLEditor::InsertTextImpl(const nsAString& aStringToInsert,
                            nsCOMPtr<nsINode>* aInOutNode,
-                           nsIContent* aChildAtOffset,
                            int32_t* aInOutOffset,
                            nsIDocument* aDoc)
 {
   // Do nothing if the node is read-only
   if (!IsModifiableNode(*aInOutNode)) {
     return NS_ERROR_FAILURE;
   }
 
-  return EditorBase::InsertTextImpl(aStringToInsert, aInOutNode, aChildAtOffset,
-                                    aInOutOffset, aDoc);
+  return EditorBase::InsertTextImpl(aStringToInsert, aInOutNode, aInOutOffset,
+                                    aDoc);
 }
 
 void
 HTMLEditor::ContentAppended(nsIDocument* aDocument,
                             nsIContent* aContainer,
                             nsIContent* aFirstNewContent)
 {
   DoContentInserted(aDocument, aContainer, aFirstNewContent, eAppended);
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -308,17 +308,16 @@ public:
   NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
                                  EStripWrappers aStripWrappers) override;
   nsresult DeleteNode(nsINode* aNode);
   NS_IMETHOD DeleteNode(nsIDOMNode* aNode) override;
   nsresult DeleteText(nsGenericDOMDataNode& aTextNode, uint32_t aOffset,
                       uint32_t aLength);
   virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
                                   nsCOMPtr<nsINode>* aInOutNode,
-                                  nsIContent* aChildAtOffset,
                                   int32_t* aInOutOffset,
                                   nsIDocument* aDoc) override;
   NS_IMETHOD_(bool) IsModifiableNode(nsIDOMNode* aNode) override;
   virtual bool IsModifiableNode(nsINode* aNode) override;
 
   NS_IMETHOD SelectAll() override;
 
   // nsICSSLoaderObserver
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -721,17 +721,16 @@ TextEditRules::WillInsertText(EditAction
     } else {
       FillBufWithPWChars(outString, outString->Length());
     }
   }
 
   // get the (collapsed) selection location
   NS_ENSURE_STATE(aSelection->GetRangeAt(0));
   nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartContainer();
-  nsIContent* selChild = aSelection->GetRangeAt(0)->GetChildAtStartOffset();
   int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset();
   NS_ENSURE_STATE(selNode);
 
   // don't put text in places that can't have it
   NS_ENSURE_STATE(mTextEditor);
   if (!EditorBase::IsTextNode(selNode) &&
       !mTextEditor->CanContainTag(*selNode, *nsGkAtoms::textTagName)) {
     return NS_ERROR_FAILURE;
@@ -749,29 +748,29 @@ TextEditRules::WillInsertText(EditAction
     // If there is one or more IME selections, its minimum offset should be
     // the insertion point.
     int32_t IMESelectionOffset =
       mTextEditor->GetIMESelectionStartOffsetIn(selNode);
     if (IMESelectionOffset >= 0) {
       selOffset = IMESelectionOffset;
     }
     rv = mTextEditor->InsertTextImpl(*outString, address_of(selNode),
-                                     selChild, &selOffset, doc);
+                                     &selOffset, doc);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     // aAction == EditAction::insertText; find where we are
     nsCOMPtr<nsINode> curNode = selNode;
     int32_t curOffset = selOffset;
 
     // don't change my selection in subtransactions
     NS_ENSURE_STATE(mTextEditor);
     AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor);
 
     rv = mTextEditor->InsertTextImpl(*outString, address_of(curNode),
-                                     selChild, &curOffset, doc);
+                                     &curOffset, doc);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (curNode) {
       // Make the caret attach to the inserted text, unless this text ends with a LF,
       // in which case make the caret attach to the next line.
       bool endsWithLF =
         !outString->IsEmpty() && outString->Last() == nsCRT::LF;
       aSelection->SetInterlinePosition(endsWithLF);
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -699,17 +699,16 @@ TextEditor::InsertLineBreak()
   ruleInfo.maxLength = mMaxTextLength;
   bool cancel, handled;
   nsresult rv = rules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!cancel && !handled) {
     // get the (collapsed) selection location
     NS_ENSURE_STATE(selection->GetRangeAt(0));
     nsCOMPtr<nsINode> selNode = selection->GetRangeAt(0)->GetStartContainer();
-    nsIContent* selChild = selection->GetRangeAt(0)->GetChildAtStartOffset();
     int32_t selOffset = selection->GetRangeAt(0)->StartOffset();
     NS_ENSURE_STATE(selNode);
 
     // don't put text in places that can't have it
     if (!IsTextNode(selNode) && !CanContainTag(*selNode,
                                                *nsGkAtoms::textTagName)) {
       return NS_ERROR_FAILURE;
     }
@@ -718,17 +717,17 @@ TextEditor::InsertLineBreak()
     nsCOMPtr<nsIDocument> doc = GetDocument();
     NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED);
 
     // don't change my selection in subtransactions
     AutoTransactionsConserveSelection dontChangeMySelection(this);
 
     // insert a linefeed character
     rv = InsertTextImpl(NS_LITERAL_STRING("\n"), address_of(selNode),
-                        selChild, &selOffset, doc);
+                        &selOffset, doc);
     if (!selNode) {
       rv = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
     }
     if (NS_SUCCEEDED(rv)) {
       // set the selection to the correct location
       rv = selection->Collapse(selNode, selOffset);
       if (NS_SUCCEEDED(rv)) {
         // see if we're at the end of the editor range
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -229,17 +229,16 @@ WSRunObject::InsertBreak(nsCOMPtr<nsINod
 
   // ready, aim, fire!
   return mHTMLEditor->CreateBRImpl(aInOutParent, aInOutOffset, aSelect);
 }
 
 nsresult
 WSRunObject::InsertText(const nsAString& aStringToInsert,
                         nsCOMPtr<nsINode>* aInOutParent,
-                        nsIContent* aChildAtOffset,
                         int32_t* aInOutOffset,
                         nsIDocument* aDoc)
 {
   // MOOSE: for now, we always assume non-PRE formatting.  Fix this later.
   // meanwhile, the pre case is handled in WillInsertText in
   // HTMLEditRules.cpp
 
   // MOOSE: for now, just getting the ws logic straight.  This implementation
@@ -352,18 +351,17 @@ WSRunObject::InsertText(const nsAString&
         prevWS = true;
       }
     } else {
       prevWS = false;
     }
   }
 
   // Ready, aim, fire!
-  mHTMLEditor->InsertTextImpl(theString, aInOutParent, aChildAtOffset,
-                              aInOutOffset, aDoc);
+  mHTMLEditor->InsertTextImpl(theString, aInOutParent, aInOutOffset, aDoc);
   return NS_OK;
 }
 
 nsresult
 WSRunObject::DeleteWSBackward()
 {
   WSPoint point = GetCharBefore(mNode, mOffset);
   NS_ENSURE_TRUE(point.mTextNode, NS_OK);  // nothing to delete
--- a/editor/libeditor/WSRunObject.h
+++ b/editor/libeditor/WSRunObject.h
@@ -219,17 +219,16 @@ public:
                                              int32_t* aInOutOffset,
                                              nsIEditor::EDirection aSelect);
 
   // InsertText inserts a string at {aInOutParent,aInOutOffset} and makes any
   // needed adjustments to ws around that point.  Example of fixup:
   // trailingws before {aInOutParent,aInOutOffset} needs to be removed.
   nsresult InsertText(const nsAString& aStringToInsert,
                       nsCOMPtr<nsINode>* aInOutNode,
-                      nsIContent* aChildAtOffset,
                       int32_t* aInOutOffset,
                       nsIDocument* aDoc);
 
   // DeleteWSBackward deletes a single visible piece of ws before the ws
   // point (the point to create the wsRunObject, passed to its constructor).
   // It makes any needed conversion to adjacent ws to retain its
   // significance.
   nsresult DeleteWSBackward();