diff --git a/mozilla/editor/libeditor/html/crashtests/420439.html b/mozilla/editor/libeditor/html/crashtests/420439.html new file mode 100644 index 00000000000..e1303307da0 --- /dev/null +++ b/mozilla/editor/libeditor/html/crashtests/420439.html @@ -0,0 +1,30 @@ + + + + + + +
+ + + diff --git a/mozilla/editor/libeditor/html/crashtests/crashtests.list b/mozilla/editor/libeditor/html/crashtests/crashtests.list index 252cb98981d..fd9d647636d 100644 --- a/mozilla/editor/libeditor/html/crashtests/crashtests.list +++ b/mozilla/editor/libeditor/html/crashtests/crashtests.list @@ -2,3 +2,4 @@ load 336081-1.xhtml # asserts (no bug?) load 382778-1.html load 407074-1.html load 407277-1.html +load 420439.html diff --git a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp index aa06b289a83..cf36afcd20f 100644 --- a/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLAbsPosition.cpp @@ -334,6 +334,11 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement) { NS_ENSURE_ARG_POINTER(aElement); + if (mGrabber) { + NS_ERROR("call HideGrabber first"); + return NS_ERROR_UNEXPECTED; + } + nsAutoString classValue; nsresult res = CheckPositionedElementBGandFG(aElement, classValue); if (NS_FAILED(res)) return res; diff --git a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp index b76aef84352..670bd760afb 100644 --- a/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLAnonymousUtils.cpp @@ -344,30 +344,29 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection) // cellElement contains the element for InlineTableEditing // absPosElement contains the element for Positioning - // first let's cancel old settings if needed - PRBool refreshResizing = (mResizedObject != nsnull); - PRBool refreshPositioning = (mAbsolutelyPositionedObject != nsnull); - PRBool refreshTableEditing = (mInlineEditedCell != nsnull); + // Note: All the Hide/Show methods below may change attributes on real + // content which means a DOMAttrModified handler may cause arbitrary + // side effects while this code runs (bug 420439). if (mIsAbsolutelyPositioningEnabled && mAbsolutelyPositionedObject && absPosElement != mAbsolutelyPositionedObject) { res = HideGrabber(); if (NS_FAILED(res)) return res; - refreshPositioning = PR_FALSE; + NS_ASSERTION(!mAbsolutelyPositionedObject, "HideGrabber failed"); } if (mIsObjectResizingEnabled && mResizedObject && mResizedObject != focusElement) { res = HideResizers(); if (NS_FAILED(res)) return res; - refreshResizing = PR_FALSE; + NS_ASSERTION(!mResizedObject, "HideResizers failed"); } if (mIsInlineTableEditingEnabled && mInlineEditedCell && mInlineEditedCell != cellElement) { res = HideInlineTableEditingUI(); if (NS_FAILED(res)) return res; - refreshTableEditing = PR_FALSE; + NS_ASSERTION(!mInlineEditedCell, "HideInlineTableEditingUI failed"); } // now, let's display all contextual UI for good @@ -376,7 +375,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection) IsModifiableNode(focusElement)) { if (nsEditProperty::img == focusTagAtom) mResizedObjectIsAnImage = PR_TRUE; - if (refreshResizing) + if (mResizedObject) res = RefreshResizers(); else res = ShowResizers(focusElement); @@ -385,7 +384,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection) if (mIsAbsolutelyPositioningEnabled && absPosElement && IsModifiableNode(absPosElement)) { - if (refreshPositioning) + if (mAbsolutelyPositionedObject) res = RefreshGrabber(); else res = ShowGrabberOnElement(absPosElement); @@ -394,7 +393,7 @@ nsHTMLEditor::CheckSelectionStateForAnonymousButtons(nsISelection * aSelection) if (mIsInlineTableEditingEnabled && cellElement && IsModifiableNode(cellElement)) { - if (refreshTableEditing) + if (mInlineEditedCell) res = RefreshInlineTableEditingUI(); else res = ShowInlineTableEditingUI(cellElement); diff --git a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp index 452ed45b438..1d70ebaa282 100644 --- a/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLInlineTableEditor.cpp @@ -71,6 +71,11 @@ nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell) if (!nsHTMLEditUtils::IsTableCell(aCell)) return NS_OK; + if (mInlineEditedCell) { + NS_ERROR("call HideInlineTableEditingUI first"); + return NS_ERROR_UNEXPECTED; + } + // the resizers and the shadow will be anonymous children of the body nsIDOMElement *bodyElement = GetRoot(); if (!bodyElement) return NS_ERROR_NULL_POINTER; diff --git a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp index eb84689fd64..96d1e5ad1f7 100644 --- a/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLObjectResizer.cpp @@ -336,6 +336,12 @@ NS_IMETHODIMP nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement) { NS_ENSURE_ARG_POINTER(aResizedElement); + + if (mResizedObject) { + NS_ERROR("call HideResizers first"); + return NS_ERROR_UNEXPECTED; + } + mResizedObject = aResizedElement; // The resizers and the shadow will be anonymous siblings of the element. @@ -476,6 +482,11 @@ nsHTMLEditor::HideResizers(void) mResizingInfo, parentContent, ps); mResizingInfo = nsnull; + if (mActivatedHandle) { + mActivatedHandle->RemoveAttribute(NS_LITERAL_STRING("_moz_activated")); + mActivatedHandle = nsnull; + } + // don't forget to remove the listeners ! nsCOMPtr piTarget = GetPIDOMEventTarget();