Bug 1406297 - Fix Document.createElement must report an exception. r=smaug
authorJohn Dai <jdai@mozilla.com>
Thu, 12 Oct 2017 04:25:00 -0400
changeset 385798 b47e0b4d65a9daf651dce59e38896856d062dfaf
parent 385797 1f4d35d137631cde34f318fac0c33421d5360dc3
child 385799 69f90636cb2168faa420a498f8f2cb88757d653d
push id96106
push userryanvm@gmail.com
push dateThu, 12 Oct 2017 13:55:09 +0000
treeherdermozilla-inbound@b47e0b4d65a9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1406297
milestone58.0a1
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
Bug 1406297 - Fix Document.createElement must report an exception. r=smaug
dom/base/CustomElementRegistry.cpp
dom/html/nsHTMLContentSink.cpp
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html.ini
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -107,23 +107,21 @@ CustomElementConstructor::Construct(cons
   if (!cx) {
     MOZ_ASSERT(aRv.Failed());
     return nullptr;
   }
 
   JS::Rooted<JSObject*> result(cx);
   JS::Rooted<JS::Value> constructor(cx, JS::ObjectValue(*mCallback));
   if (!JS::Construct(cx, constructor, JS::HandleValueArray::empty(), &result)) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   RefPtr<Element> element;
   if (NS_FAILED(UNWRAP_OBJECT(Element, &result, element))) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   return element.forget();
 }
 //-----------------------------------------------------
 // CustomElementData
 
@@ -897,17 +895,17 @@ DoUpgrade(Element* aElement,
   // Rethrow the exception since it might actually throw the exception from the
   // upgrade steps back out to the caller of document.createElement.
   RefPtr<Element> constructResult =
     aConstructor->Construct("Custom Element Upgrade", aRv);
   if (aRv.Failed()) {
     return;
   }
 
-  if (constructResult.get() != aElement) {
+  if (!constructResult || constructResult.get() != aElement) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 }
 
 } // anonymous namespace
 
 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -220,28 +220,33 @@ public:
   };
 
   Node* mStack;
   int32_t mStackSize;
   int32_t mStackPos;
 };
 
 static void
-DoCustomElementCreate(Element** aElement, nsIDocument* aDoc,
+DoCustomElementCreate(Element** aElement, nsIDocument* aDoc, nsAtom* aLocalName,
                       CustomElementConstructor* aConstructor, ErrorResult& aRv)
 {
   RefPtr<Element> element =
     aConstructor->Construct("Custom Element Create", aRv);
-  if (aRv.Failed() || !element->IsHTMLElement()) {
+  if (aRv.Failed()) {
+    return;
+  }
+
+  if (!element || !element->IsHTMLElement()) {
     aRv.ThrowTypeError<MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE>(NS_LITERAL_STRING("HTMLElement"));
     return;
   }
 
   if (aDoc != element->OwnerDoc() || element->GetParentNode() ||
-      element->HasChildren() || element->GetAttrCount()) {
+      element->HasChildren() || element->GetAttrCount() ||
+      element->NodeInfo()->NameAtom() != aLocalName) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   element.forget(aElement);
 }
 
 nsresult
@@ -303,29 +308,30 @@ NS_NewHTMLElement(Element** aResult, alr
       // SetCustomElementData().
       RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom();
       RefPtr<nsAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
       // Built-in element
       *aResult = CreateHTMLElement(tag, nodeInfo.forget(), aFromParser).take();
       (*aResult)->SetCustomElementData(new CustomElementData(typeAtom));
       if (synchronousCustomElements) {
         CustomElementRegistry::Upgrade(*aResult, definition, rv);
+        if (rv.MaybeSetPendingException(cx)) {
+          aes.ReportException();
+        }
       } else {
         nsContentUtils::EnqueueUpgradeReaction(*aResult, definition);
       }
 
-      if (rv.MaybeSetPendingException(cx)) {
-        aes.ReportException();
-      }
       return NS_OK;
     }
 
     // Step 6.1.
     if (synchronousCustomElements) {
       DoCustomElementCreate(aResult, nodeInfo->GetDocument(),
+                            nodeInfo->NameAtom(),
                             definition->mConstructor, rv);
       if (rv.MaybeSetPendingException(cx)) {
         NS_IF_ADDREF(*aResult = NS_NewHTMLUnknownElement(nodeInfo.forget(), aFromParser));
       }
       return NS_OK;
     }
 
     // Step 6.2.
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/custom-element-exception.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[custom-element-exception.html]
-  type: testharness
-  [Test that exceptions from the constructor of a custom element inside a module are propagated as expected.\n]
-    expected: FAIL
-