Title: [205410] trunk
Revision
205410
Author
[email protected]
Date
2016-09-03 16:25:47 -0700 (Sat, 03 Sep 2016)

Log Message

Unbreak customElements.whenDefined after r205383 with a crash fix
https://bugs.webkit.org/show_bug.cgi?id=161562

Reviewed by Darin Adler.

Source/WebCore:

The crash was caused by DeferredWrapper::contextDestroyed not calling ContextDestructionObserver::contextDestroyed.

This caused m_scriptExecutionContext to not being set to nullptr when the Document was destroyed before DOMWindow
during a single GC sweeping, and resulted in a use-after-free in ContextDestructionObserver's destructor.

Fixed the crash and reverted r205383.

Tests: fast/custom-elements/CustomElementRegistry.html

* bindings/js/JSCustomElementRegistryCustom.cpp:
(WebCore::whenDefinedPromise):
* bindings/js/JSDOMPromise.cpp:
(WebCore::DeferredWrapper::contextDestroyed): Fixed the crash.
* dom/CustomElementRegistry.cpp:
(WebCore::CustomElementRegistry::addElementDefinition):
* dom/CustomElementRegistry.h:
(WebCore::CustomElementRegistry::promiseMap):

LayoutTests:

Revert r205383 now that all test cases pass.

* fast/custom-elements/CustomElementRegistry-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (205409 => 205410)


--- trunk/LayoutTests/ChangeLog	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/LayoutTests/ChangeLog	2016-09-03 23:25:47 UTC (rev 205410)
@@ -1,3 +1,14 @@
+2016-09-03  Ryosuke Niwa  <[email protected]>
+
+        Unbreak customElements.whenDefined after r205383 with a crash fix
+        https://bugs.webkit.org/show_bug.cgi?id=161562
+
+        Reviewed by Darin Adler.
+
+        Revert r205383 now that all test cases pass.
+
+        * fast/custom-elements/CustomElementRegistry-expected.txt:
+
 2016-09-03  Chris Dumez  <[email protected]>
 
         Align cross-Origin Object.getOwnPropertyNames() with the HTML specification

Modified: trunk/LayoutTests/fast/custom-elements/CustomElementRegistry-expected.txt (205409 => 205410)


--- trunk/LayoutTests/fast/custom-elements/CustomElementRegistry-expected.txt	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/LayoutTests/fast/custom-elements/CustomElementRegistry-expected.txt	2016-09-03 23:25:47 UTC (rev 205410)
@@ -29,11 +29,11 @@
 PASS customElements.get must return undefined when the registry does not contain an entry with the given name 
 PASS customElements.get must return undefined when the registry does not contain an entry with the given name even if the name was not a valid custom element name 
 PASS customElements.get return the constructor of the entry with the given name when there is a matching entry. 
-FAIL customElements.whenDefined must return a promise for a valid custom element name assert_true: expected true got false
+PASS customElements.whenDefined must return a promise for a valid custom element name 
 PASS customElements.whenDefined must return the same promise each time invoked for a valid custom element name which has not been defined 
-FAIL customElements.whenDefined must return an unresolved promise when the registry does not contain the entry with the given name undefined is not an object (evaluating 'customElements.whenDefined('a-b').then')
+PASS customElements.whenDefined must return an unresolved promise when the registry does not contain the entry with the given name 
 PASS customElements.whenDefined must return a rejected promise when the given name is not a valid custom element name 
 PASS customElements.whenDefined must return a resolved promise when the registry contains the entry with the given name 
 PASS customElements.whenDefined must return a new resolved promise each time invoked when the registry contains the entry with the given name 
-FAIL A promise returned by customElements.whenDefined must be resolved by "define" undefined is not an object (evaluating 'promise.then')
+PASS A promise returned by customElements.whenDefined must be resolved by "define" 
 

Modified: trunk/Source/WebCore/ChangeLog (205409 => 205410)


--- trunk/Source/WebCore/ChangeLog	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/Source/WebCore/ChangeLog	2016-09-03 23:25:47 UTC (rev 205410)
@@ -1,3 +1,28 @@
+2016-09-03  Ryosuke Niwa  <[email protected]>
+
+        Unbreak customElements.whenDefined after r205383 with a crash fix
+        https://bugs.webkit.org/show_bug.cgi?id=161562
+
+        Reviewed by Darin Adler.
+
+        The crash was caused by DeferredWrapper::contextDestroyed not calling ContextDestructionObserver::contextDestroyed.
+
+        This caused m_scriptExecutionContext to not being set to nullptr when the Document was destroyed before DOMWindow
+        during a single GC sweeping, and resulted in a use-after-free in ContextDestructionObserver's destructor.
+
+        Fixed the crash and reverted r205383.
+
+        Tests: fast/custom-elements/CustomElementRegistry.html
+
+        * bindings/js/JSCustomElementRegistryCustom.cpp:
+        (WebCore::whenDefinedPromise):
+        * bindings/js/JSDOMPromise.cpp:
+        (WebCore::DeferredWrapper::contextDestroyed): Fixed the crash.
+        * dom/CustomElementRegistry.cpp:
+        (WebCore::CustomElementRegistry::addElementDefinition):
+        * dom/CustomElementRegistry.h:
+        (WebCore::CustomElementRegistry::promiseMap):
+
 2016-09-03  Chris Dumez  <[email protected]>
 
         Align cross-Origin Object.getOwnPropertyNames() with the HTML specification

Modified: trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp (205409 => 205410)


--- trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp	2016-09-03 23:25:47 UTC (rev 205410)
@@ -182,7 +182,11 @@
         return jsPromise.promise();
     }
 
-    return jsUndefined();
+    auto result = registry.promiseMap().ensure(localName, [&] {
+        return DeferredWrapper::create(&state, &globalObject, JSPromiseDeferred::create(&state, &globalObject));
+    });
+
+    return result.iterator->value->promise();
 }
 
 JSValue JSCustomElementRegistry::whenDefined(ExecState& state)

Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp (205409 => 205410)


--- trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp	2016-09-03 23:25:47 UTC (rev 205410)
@@ -59,6 +59,7 @@
 
 void DeferredWrapper::contextDestroyed()
 {
+    ActiveDOMCallback::contextDestroyed();
     clear();
 }
 

Modified: trunk/Source/WebCore/dom/CustomElementRegistry.cpp (205409 => 205410)


--- trunk/Source/WebCore/dom/CustomElementRegistry.cpp	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/Source/WebCore/dom/CustomElementRegistry.cpp	2016-09-03 23:25:47 UTC (rev 205410)
@@ -78,6 +78,9 @@
 
     if (auto* document = m_window.document())
         enqueueUpgradeInShadowIncludingTreeOrder(*document, elementInterface.get());
+
+    if (auto promise = m_promiseMap.take(localName))
+        promise.value()->resolve(nullptr);
 }
 
 JSCustomElementInterface* CustomElementRegistry::findInterface(const Element& element) const

Modified: trunk/Source/WebCore/dom/CustomElementRegistry.h (205409 => 205410)


--- trunk/Source/WebCore/dom/CustomElementRegistry.h	2016-09-03 22:50:55 UTC (rev 205409)
+++ trunk/Source/WebCore/dom/CustomElementRegistry.h	2016-09-03 23:25:47 UTC (rev 205410)
@@ -66,6 +66,8 @@
 
     JSC::JSValue get(const AtomicString&);
 
+    HashMap<AtomicString, Ref<DeferredWrapper>>& promiseMap() { return m_promiseMap; }
+
 private:
     CustomElementRegistry(DOMWindow&);
 
@@ -72,6 +74,7 @@
     DOMWindow& m_window;
     HashMap<AtomicString, Ref<JSCustomElementInterface>> m_nameMap;
     HashMap<const JSC::JSObject*, JSCustomElementInterface*> m_constructorMap;
+    HashMap<AtomicString, Ref<DeferredWrapper>> m_promiseMap;
 
     bool m_elementDefinitionIsRunning { false };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to