Bug 590387 - Crash [@ nsGenericHTMLFormElement::UpdateFormOwner] when attaching an element with @form set to an element which is not in a document. r=sicking a2.0=blocking
authorMounir Lamouri <mounir.lamouri@gmail.com>
Wed, 25 Aug 2010 22:45:43 +0200
changeset 51492 a1e65a7730f460d90e87b7522108ec5dcc8ef655
parent 51491 d4f75e835532ff2df6f1df9f8a4c1c2da63850d0
child 51493 b5567c5bbda9d17baa2bb76f27e5b6836252d1cf
push idunknown
push userunknown
push dateunknown
reviewerssicking
bugs590387
milestone2.0b5pre
Bug 590387 - Crash [@ nsGenericHTMLFormElement::UpdateFormOwner] when attaching an element with @form set to an element which is not in a document. r=sicking a2.0=blocking
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
layout/generic/crashtests/590387.html
layout/generic/crashtests/crashtests.list
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2478,17 +2478,24 @@ nsGenericHTMLFormElement::BindToTree(nsI
       aDocument &&
       aDocument->GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE &&
       nsContentUtils::GetBoolPref("browser.autofocus", PR_TRUE)) {
     nsCOMPtr<nsIRunnable> event = new nsAutoFocusEvent(this);
     rv = NS_DispatchToCurrentThread(event);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  if (aParent || HasAttr(kNameSpaceID_None, nsGkAtoms::form)) {
+  // If @form is set, the element *has* to be in a document, otherwise it
+  // wouldn't be possible to find an element with the corresponding id.
+  // If @form isn't set, the element *has* to have a parent, otherwise it
+  // wouldn't be possible to find a form ancestor.
+  // We should not call UpdateFormOwner if none of these coniditions are
+  // fulfilled.
+  if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ? !!GetCurrentDoc()
+                                                  : !!aParent) {
     UpdateFormOwner(true, nsnull);
   }
 
   return NS_OK;
 }
 
 void
 nsGenericHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
@@ -2894,17 +2901,18 @@ nsGenericHTMLFormElement::UpdateFormOwne
         if (aBindToTree) {
           element = AddFormIdObserver();
         } else {
           element = aFormIdElement;
         }
 
         NS_ASSERTION(GetCurrentDoc(), "The element should be in a document "
                                       "when UpdateFormOwner is called!");
-        NS_ASSERTION(element == GetCurrentDoc()->GetElementById(formId),
+        NS_ASSERTION(!GetCurrentDoc() ||
+                     element == GetCurrentDoc()->GetElementById(formId),
                      "element should be equals to the current element "
                      "associated with the id in @form!");
 
         if (element && element->Tag() == nsGkAtoms::form &&
             element->IsHTML()) {
           mForm = static_cast<nsHTMLFormElement*>(element);
         }
       }
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -869,16 +869,19 @@ protected:
 
   /**
    * This method will update the form owner, using @form or looking to a parent.
    *
    * @param aBindToTree Whether the element is being attached to the tree.
    * @param aFormIdElement The element associated with the id in @form. If
    * aBindToTree is false, aFormIdElement *must* contain the element associated
    * with the id in @form. Otherwise, it *must* be null.
+   *
+   * @note Callers of UpdateFormOwner have to be sure the element is in a
+   * document (GetCurrentDoc() != nsnull).
    */
   void UpdateFormOwner(bool aBindToTree, Element* aFormIdElement);
 
   /**
    * Add a form id observer which will observe when the element with the id in
    * @form will change.
    *
    * @return The element associated with the current id in @form (may be null).
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/590387.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+document.createElement("div").innerHTML = "<output form=x>";
+</script>
+</head>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -328,8 +328,9 @@ load 564968.xhtml
 load 570160.html
 load 571618-1.svg
 load 574958.xhtml
 load 585598-1.xhtml
 load 586806-1.html
 load 586806-2.html
 load 586806-3.html
 load 586973-1.html
+load 590387.html