Bug 1130651 - Don't throw IndexSizeError from insertText command draft
authorAryeh Gregor <ayg@aryeh.name>
Thu, 30 Mar 2017 18:36:17 +0300
changeset 555002 b7e08c5449b9bae1e7f7b943e67b383178daa30d
parent 552445 d4af7ec6cfcd9b81cd1f433a00b412de61e95b62
child 622494 52a8d3f03b3e9a71a49c323f694ff8558096c36a
push id52112
push userbmo:ayg@aryeh.name
push dateMon, 03 Apr 2017 12:45:26 +0000
bugs1130651
milestone55.0a1
Bug 1130651 - Don't throw IndexSizeError from insertText command MozReview-Commit-ID: 7AXGvenAfWv
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_bug1130651.html
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1338,96 +1338,102 @@ HTMLEditRules::WillInsertText(EditAction
     // don't spaz my selection in subtransactions
     NS_ENSURE_STATE(mHTMLEditor);
     AutoTransactionsConserveSelection dontSpazMySelection(mHTMLEditor);
     nsAutoString tString(*inString);
     const char16_t *unicodeBuf = tString.get();
     int32_t pos = 0;
     NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
 
-    // for efficiency, break out the pre case separately.  This is because
-    // its a lot cheaper to search the input string for only newlines than
-    // it is to search for both tabs and newlines.
-    if (isPRE || IsPlaintextEditor()) {
-      while (unicodeBuf && pos != -1 &&
-             pos < static_cast<int32_t>(inString->Length())) {
-        int32_t oldPos = pos;
-        int32_t subStrLen;
-        pos = tString.FindChar(nsCRT::LF, oldPos);
-
-        if (pos != -1) {
-          subStrLen = pos - oldPos;
-          // if first char is newline, then use just it
-          if (!subStrLen) {
-            subStrLen = 1;
+    {
+      NS_ENSURE_STATE(mHTMLEditor);
+      AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
+                                address_of(selNode), &selOffset);
+
+      // for efficiency, break out the pre case separately.  This is because
+      // its a lot cheaper to search the input string for only newlines than
+      // it is to search for both tabs and newlines.
+      if (isPRE || IsPlaintextEditor()) {
+        while (unicodeBuf && pos != -1 &&
+               pos < static_cast<int32_t>(inString->Length())) {
+          int32_t oldPos = pos;
+          int32_t subStrLen;
+          pos = tString.FindChar(nsCRT::LF, oldPos);
+
+          if (pos != -1) {
+            subStrLen = pos - oldPos;
+            // if first char is newline, then use just it
+            if (!subStrLen) {
+              subStrLen = 1;
+            }
+          } else {
+            subStrLen = tString.Length() - oldPos;
+            pos = tString.Length();
           }
-        } else {
-          subStrLen = tString.Length() - oldPos;
-          pos = tString.Length();
-        }
-
-        nsDependentSubstring subStr(tString, oldPos, subStrLen);
-
-        // is it a return?
-        if (subStr.Equals(newlineStr)) {
-          NS_ENSURE_STATE(mHTMLEditor);
-          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),
-                                           &curOffset, doc);
-          NS_ENSURE_SUCCESS(rv, rv);
+
+          nsDependentSubstring subStr(tString, oldPos, subStrLen);
+
+          // is it a return?
+          if (subStr.Equals(newlineStr)) {
+            NS_ENSURE_STATE(mHTMLEditor);
+            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),
+                                             &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 &&
-             pos < static_cast<int32_t>(inString->Length())) {
-        int32_t oldPos = pos;
-        int32_t subStrLen;
-        pos = tString.FindCharInSet(specialChars, oldPos);
-
-        if (pos != -1) {
-          subStrLen = pos - oldPos;
-          // if first char is newline, then use just it
-          if (!subStrLen) {
-            subStrLen = 1;
+      } else {
+        NS_NAMED_LITERAL_STRING(tabStr, "\t");
+        NS_NAMED_LITERAL_STRING(spacesStr, "    ");
+        char specialChars[] = {TAB, nsCRT::LF, 0};
+        while (unicodeBuf && pos != -1 &&
+               pos < static_cast<int32_t>(inString->Length())) {
+          int32_t oldPos = pos;
+          int32_t subStrLen;
+          pos = tString.FindCharInSet(specialChars, oldPos);
+
+          if (pos != -1) {
+            subStrLen = pos - oldPos;
+            // if first char is newline, then use just it
+            if (!subStrLen) {
+              subStrLen = 1;
+            }
+          } else {
+            subStrLen = tString.Length() - oldPos;
+            pos = tString.Length();
           }
-        } else {
-          subStrLen = tString.Length() - oldPos;
-          pos = tString.Length();
-        }
-
-        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), &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), &curOffset, doc);
-          NS_ENSURE_SUCCESS(rv, rv);
+
+          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), &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), &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
     // the correct portion of the document.
     if (!mDocChangeRange) {
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -191,16 +191,17 @@ subsuite = clipboard
 [test_bug1094000.html]
 [test_bug1100966.html]
 skip-if = os == 'android'
 [test_bug1102906.html]
 skip-if = os == 'android'
 [test_bug1101392.html]
 subsuite = clipboard
 [test_bug1109465.html]
+[test_bug1130651.html]
 [test_bug1140105.html]
 [test_bug1140617.html]
 subsuite = clipboard
 skip-if = toolkit == 'android' # bug 1299578
 [test_bug1153237.html]
 [test_bug1154791.html]
 skip-if = os == 'android'
 [test_bug1162952.html]
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_bug1130651.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Test for Bug 1130651</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1332876">Mozilla Bug 1332876</a>
+<div contenteditable>a b</div>
+<script>
+var div = document.querySelector("div");
+div.focus();
+getSelection().collapse(div.firstChild, 2);
+try {
+  document.execCommand("inserttext", false, "\n");
+  ok(true, "No exception thrown");
+} catch(e) {
+  ok(false, "Exception: " + e);
+}
+</script>