diff --git a/editor/libeditor/html/crashtests/467647-1.html b/editor/libeditor/html/crashtests/467647-1.html
new file mode 100644
index 000000000000..7bb4271d7429
--- /dev/null
+++ b/editor/libeditor/html/crashtests/467647-1.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+One
+
+
diff --git a/editor/libeditor/html/crashtests/crashtests.list b/editor/libeditor/html/crashtests/crashtests.list
index 3450d342193e..90b3520da202 100644
--- a/editor/libeditor/html/crashtests/crashtests.list
+++ b/editor/libeditor/html/crashtests/crashtests.list
@@ -4,3 +4,4 @@ load 407074-1.html
load 407277-1.html
load 420439.html
load 428489-1.html
+load 467647-1.html
diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp
index 8f441cd5d8d3..d71fbacafcd9 100644
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -84,6 +84,7 @@
#include "nsFrameSelection.h"
#include "nsIDOM3Node.h"
#include "nsContentUtils.h"
+#include "nsTArray.h"
//const static char* kMOZEditorBogusNodeAttr="MOZ_EDITOR_BOGUS_NODE";
//const static char* kMOZEditorBogusNodeValue="TRUE";
@@ -5758,39 +5759,42 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray& inArrayOfRanges,
if (!aDontTouchContent)
{
- nsVoidArray rangeItemArray;
+ nsAutoTArray rangeItemArray;
+ if (!rangeItemArray.AppendElements(rangeCount)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ NS_ASSERTION(rangeCount == rangeItemArray.Length(), "How did that happen?");
+
// first register ranges for special editor gravity
- // XXXbz doesn't this leak all the nsRangeStore structs on error
- // conditions??
for (i = 0; i < (PRInt32)rangeCount; i++)
{
opRange = inArrayOfRanges[0];
- nsRangeStore *item = new nsRangeStore();
- if (!item) return NS_ERROR_NULL_POINTER;
+ nsRangeStore *item = rangeItemArray.Elements() + i;
item->StoreRange(opRange);
mHTMLEditor->mRangeUpdater.RegisterRangeItem(item);
- rangeItemArray.AppendElement((void*)item);
inArrayOfRanges.RemoveObjectAt(0);
}
- // now bust up inlines
- for (i = rangeCount-1; i >= 0; i--)
+ // now bust up inlines. Safe to start at rangeCount-1, since we
+ // asserted we have enough items above.
+ for (i = rangeCount-1; i >= 0 && NS_SUCCEEDED(res); i--)
{
- nsRangeStore *item = (nsRangeStore*)rangeItemArray.ElementAt(i);
- res = BustUpInlinesAtRangeEndpoints(*item);
- if (NS_FAILED(res)) return res;
+ res = BustUpInlinesAtRangeEndpoints(rangeItemArray[i]);
}
// then unregister the ranges
for (i = 0; i < rangeCount; i++)
{
- nsRangeStore *item = (nsRangeStore*)rangeItemArray.ElementAt(0);
- if (!item) return NS_ERROR_NULL_POINTER;
- rangeItemArray.RemoveElementAt(0);
+ nsRangeStore *item = rangeItemArray.Elements() + i;
mHTMLEditor->mRangeUpdater.DropRangeItem(item);
- res = item->GetRange(address_of(opRange));
- if (NS_FAILED(res)) return res;
- delete item;
+ nsresult res2 = item->GetRange(address_of(opRange));
+ if (NS_FAILED(res2) && NS_SUCCEEDED(res)) {
+ // Remember the failure, but keep going so we make sure to unregister
+ // all our range items.
+ res = res2;
+ }
inArrayOfRanges.AppendObject(opRange);
- }
+ }
+ if (NS_FAILED(res)) return res;
}
// gather up a list of all the nodes
for (i = 0; i < rangeCount; i++)