Title: [210468] trunk
Revision
210468
Author
[email protected]
Date
2017-01-06 20:02:06 -0800 (Fri, 06 Jan 2017)

Log Message

Regression(r189230): DOM Callbacks may use wrong global object
https://bugs.webkit.org/show_bug.cgi?id=166784

Reviewed by Mark Lam.

Source/WebCore:

DOM Callbacks could end up using the wrong global object after r189230
because we were getting the globalObject from the callback object
instead of the one at the point the callback object was passed in by
_javascript_. This patch fixes the issue.

Test: fast/frames/frame-window-as-callback.html

* bindings/js/JSCallbackData.cpp:
(WebCore::JSCallbackData::invokeCallback):
* bindings/js/JSCallbackData.h:
(WebCore::JSCallbackData::globalObject):
(WebCore::JSCallbackData::JSCallbackData):
(WebCore::JSCallbackDataStrong::JSCallbackDataStrong):
(WebCore::JSCallbackDataStrong::callback):
(WebCore::JSCallbackDataStrong::invokeCallback):
(WebCore::JSCallbackDataWeak::JSCallbackDataWeak):
(WebCore::JSCallbackDataWeak::callback):
(WebCore::JSCallbackDataWeak::invokeCallback):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateCallbackImplementationContent):

LayoutTests:

Add layout test coverage.

* fast/frames/frame-window-as-callback-expected.txt: Added.
* fast/frames/frame-window-as-callback.html: Added.
* fast/frames/resources/wrong-global-object.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (210467 => 210468)


--- trunk/LayoutTests/ChangeLog	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/LayoutTests/ChangeLog	2017-01-07 04:02:06 UTC (rev 210468)
@@ -1,3 +1,16 @@
+2017-01-06  Chris Dumez  <[email protected]>
+
+        Regression(r189230): DOM Callbacks may use wrong global object
+        https://bugs.webkit.org/show_bug.cgi?id=166784
+
+        Reviewed by Mark Lam.
+
+        Add layout test coverage.
+
+        * fast/frames/frame-window-as-callback-expected.txt: Added.
+        * fast/frames/frame-window-as-callback.html: Added.
+        * fast/frames/resources/wrong-global-object.html: Added.
+
 2017-01-06  Tim Horton  <[email protected]>
 
         Minor cleanups to IndentOutdentCommand and related code

Added: trunk/LayoutTests/fast/frames/frame-window-as-callback-expected.txt (0 => 210468)


--- trunk/LayoutTests/fast/frames/frame-window-as-callback-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/frame-window-as-callback-expected.txt	2017-01-07 04:02:06 UTC (rev 210468)
@@ -0,0 +1,10 @@
+Tests that we are using the right global object for DOM callbacks.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS: Global object was the right one.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/frames/frame-window-as-callback.html (0 => 210468)


--- trunk/LayoutTests/fast/frames/frame-window-as-callback.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/frame-window-as-callback.html	2017-01-07 04:02:06 UTC (rev 210468)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that we are using the right global object for DOM callbacks.");
+jsTestIsAsync = true;
+
+document.result = "PASS: Global object was the right one.";
+var f = document.body.appendChild(document.createElement("iframe"));
+f._onload_ = function() {
+    f._onload_ = null;
+
+    try {
+        var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, f.contentWindow);
+        iterator.nextNode();
+    } catch(e) {
+        e.constructor.constructor("debug(document.result)")();
+    }
+
+    finishJSTest();
+};
+
+f.src = ""
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/frames/resources/wrong-global-object.html (0 => 210468)


--- trunk/LayoutTests/fast/frames/resources/wrong-global-object.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/resources/wrong-global-object.html	2017-01-07 04:02:06 UTC (rev 210468)
@@ -0,0 +1,4 @@
+<script src=""
+<script>
+document.result = "FAIL: Wrong global object was used.";
+</script>

Modified: trunk/Source/WebCore/ChangeLog (210467 => 210468)


--- trunk/Source/WebCore/ChangeLog	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/ChangeLog	2017-01-07 04:02:06 UTC (rev 210468)
@@ -1,3 +1,31 @@
+2017-01-06  Chris Dumez  <[email protected]>
+
+        Regression(r189230): DOM Callbacks may use wrong global object
+        https://bugs.webkit.org/show_bug.cgi?id=166784
+
+        Reviewed by Mark Lam.
+
+        DOM Callbacks could end up using the wrong global object after r189230
+        because we were getting the globalObject from the callback object
+        instead of the one at the point the callback object was passed in by
+        _javascript_. This patch fixes the issue.
+
+        Test: fast/frames/frame-window-as-callback.html
+
+        * bindings/js/JSCallbackData.cpp:
+        (WebCore::JSCallbackData::invokeCallback):
+        * bindings/js/JSCallbackData.h:
+        (WebCore::JSCallbackData::globalObject):
+        (WebCore::JSCallbackData::JSCallbackData):
+        (WebCore::JSCallbackDataStrong::JSCallbackDataStrong):
+        (WebCore::JSCallbackDataStrong::callback):
+        (WebCore::JSCallbackDataStrong::invokeCallback):
+        (WebCore::JSCallbackDataWeak::JSCallbackDataWeak):
+        (WebCore::JSCallbackDataWeak::callback):
+        (WebCore::JSCallbackDataWeak::invokeCallback):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateCallbackImplementationContent):
+
 2017-01-06  Andy Estes  <[email protected]>
 
         [Cocoa] Consolidate duplicate copies of WebArchiveDumpSupport in DRT and WKTR into WebCoreTestSupport

Modified: trunk/Source/WebCore/bindings/js/JSCallbackData.cpp (210467 => 210468)


--- trunk/Source/WebCore/bindings/js/JSCallbackData.cpp	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/js/JSCallbackData.cpp	2017-01-07 04:02:06 UTC (rev 210468)
@@ -39,14 +39,11 @@
     
 namespace WebCore {
 
-JSValue JSCallbackData::invokeCallback(JSObject* callback, MarkedArgumentBuffer& args, CallbackType method, PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
+JSValue JSCallbackData::invokeCallback(JSDOMGlobalObject& globalObject, JSObject* callback, MarkedArgumentBuffer& args, CallbackType method, PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
 {
     ASSERT(callback);
 
-    auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(callback->globalObject());
-    ASSERT(globalObject);
-
-    ExecState* exec = globalObject->globalExec();
+    ExecState* exec = globalObject.globalExec();
     JSValue function;
     CallData callData;
     CallType callType = CallType::None;
@@ -73,7 +70,7 @@
     ASSERT(!function.isEmpty());
     ASSERT(callType != CallType::None);
 
-    ScriptExecutionContext* context = globalObject->scriptExecutionContext();
+    ScriptExecutionContext* context = globalObject.scriptExecutionContext();
     // We will fail to get the context if the frame has been detached.
     if (!context)
         return JSValue();

Modified: trunk/Source/WebCore/bindings/js/JSCallbackData.h (210467 => 210468)


--- trunk/Source/WebCore/bindings/js/JSCallbackData.h	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/js/JSCallbackData.h	2017-01-07 04:02:06 UTC (rev 210468)
@@ -46,10 +46,13 @@
 public:
     enum class CallbackType { Function, Object, FunctionOrObject };
 
+    JSDOMGlobalObject* globalObject() { return m_globalObject.get(); }
+
 protected:
-    JSCallbackData()
+    explicit JSCallbackData(JSDOMGlobalObject* globalObject)
+        : m_globalObject(globalObject)
 #ifndef NDEBUG
-        : m_thread(currentThread())
+        , m_thread(currentThread())
 #endif
     {
     }
@@ -61,9 +64,10 @@
 #endif
     }
     
-    static JSC::JSValue invokeCallback(JSC::JSObject* callback, JSC::MarkedArgumentBuffer&, CallbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException);
+    static JSC::JSValue invokeCallback(JSDOMGlobalObject&, JSC::JSObject* callback, JSC::MarkedArgumentBuffer&, CallbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException);
 
 private:
+    JSC::Weak<JSDOMGlobalObject> m_globalObject;
 #ifndef NDEBUG
     ThreadIdentifier m_thread;
 #endif
@@ -71,17 +75,21 @@
 
 class JSCallbackDataStrong : public JSCallbackData {
 public:
-    JSCallbackDataStrong(JSC::JSObject* callback, void*)
-        : m_callback(callback->globalObject()->vm(), callback)
+    JSCallbackDataStrong(JSC::JSObject* callback, JSDOMGlobalObject* globalObject, void*)
+        : JSCallbackData(globalObject)
+        , m_callback(globalObject->vm(), callback)
     {
     }
 
     JSC::JSObject* callback() { return m_callback.get(); }
-    JSDOMGlobalObject* globalObject() { return JSC::jsCast<JSDOMGlobalObject*>(m_callback->globalObject()); }
 
     JSC::JSValue invokeCallback(JSC::MarkedArgumentBuffer& args, CallbackType callbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
     {
-        return JSCallbackData::invokeCallback(callback(), args, callbackType, functionName, returnedException);
+        auto* globalObject = this->globalObject();
+        if (!globalObject)
+            return { };
+
+        return JSCallbackData::invokeCallback(*globalObject, callback(), args, callbackType, functionName, returnedException);
     }
 
 private:
@@ -90,17 +98,21 @@
 
 class JSCallbackDataWeak : public JSCallbackData {
 public:
-    JSCallbackDataWeak(JSC::JSObject* callback, void* owner)
-        : m_callback(callback, &m_weakOwner, owner)
+    JSCallbackDataWeak(JSC::JSObject* callback, JSDOMGlobalObject* globalObject, void* owner)
+        : JSCallbackData(globalObject)
+        , m_callback(callback, &m_weakOwner, owner)
     {
     }
 
     JSC::JSObject* callback() { return m_callback.get(); }
-    JSDOMGlobalObject* globalObject() { return JSC::jsCast<JSDOMGlobalObject*>(m_callback->globalObject()); }
 
     JSC::JSValue invokeCallback(JSC::MarkedArgumentBuffer& args, CallbackType callbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
     {
-        return JSCallbackData::invokeCallback(callback(), args, callbackType, functionName, returnedException);
+        auto* globalObject = this->globalObject();
+        if (!globalObject)
+            return { };
+
+        return JSCallbackData::invokeCallback(*globalObject, callback(), args, callbackType, functionName, returnedException);
     }
 
 private:

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (210467 => 210468)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-01-07 04:02:06 UTC (rev 210468)
@@ -4755,7 +4755,7 @@
         push(@$contentRef, "    : ${name}()\n");
     }
     push(@$contentRef, "    , ActiveDOMCallback(globalObject->scriptExecutionContext())\n");
-    push(@$contentRef, "    , m_data(new ${callbackDataType}(callback, this))\n");
+    push(@$contentRef, "    , m_data(new ${callbackDataType}(callback, globalObject, this))\n");
     push(@$contentRef, "{\n");
     push(@$contentRef, "}\n\n");
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.cpp (210467 => 210468)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.cpp	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.cpp	2017-01-07 04:02:06 UTC (rev 210468)
@@ -37,7 +37,7 @@
 JSTestCallbackFunction::JSTestCallbackFunction(JSObject* callback, JSDOMGlobalObject* globalObject)
     : TestCallbackFunction()
     , ActiveDOMCallback(globalObject->scriptExecutionContext())
-    , m_data(new JSCallbackDataStrong(callback, this))
+    , m_data(new JSCallbackDataStrong(callback, globalObject, this))
 {
 }
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp (210467 => 210468)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp	2017-01-07 04:02:06 UTC (rev 210468)
@@ -33,7 +33,7 @@
 JSTestCallbackFunctionWithTypedefs::JSTestCallbackFunctionWithTypedefs(JSObject* callback, JSDOMGlobalObject* globalObject)
     : TestCallbackFunctionWithTypedefs()
     , ActiveDOMCallback(globalObject->scriptExecutionContext())
-    , m_data(new JSCallbackDataStrong(callback, this))
+    , m_data(new JSCallbackDataStrong(callback, globalObject, this))
 {
 }
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp (210467 => 210468)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp	2017-01-07 03:49:04 UTC (rev 210467)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp	2017-01-07 04:02:06 UTC (rev 210468)
@@ -40,7 +40,7 @@
 JSTestCallbackInterface::JSTestCallbackInterface(JSObject* callback, JSDOMGlobalObject* globalObject)
     : TestCallbackInterface()
     , ActiveDOMCallback(globalObject->scriptExecutionContext())
-    , m_data(new JSCallbackDataStrong(callback, this))
+    , m_data(new JSCallbackDataStrong(callback, globalObject, this))
 {
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to