[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

dglazkov at chromium.org dglazkov at chromium.org
Thu Apr 8 00:31:31 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d8d5004cc0fca148eb1e697ce2ef8fbc88a7879d
Author: dglazkov at chromium.org <dglazkov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 10 21:42:49 2009 +0000

    WebCore:
    
    2009-12-10  Dimitri Glazkov  <dglazkov at chromium.org>
    
            Reviewed by Adam Barth.
    
            [V8] Events created in isolated worlds may fire in main world.
            https://bugs.webkit.org/show_bug.cgi?id=32386
    
            Test: http/tests/security/isolatedWorld/events.html
    
            * WebCore.gypi: Added WorldContextHandle.
            * bindings/v8/ScriptEventListener.cpp:
            (WebCore::createAttributeEventListener): Added WorldContextHandle params.
            * bindings/v8/SharedPersistent.h: Fixed a few style/include issues.
            * bindings/v8/V8AbstractEventListener.cpp:
            (WebCore::V8AbstractEventListener::V8AbstractEventListener): Added WorldContextHandle params.
            (WebCore::V8AbstractEventListener::handleEvent): Adjusted context retrieval to use WorldContextHandle.
            (WebCore::V8AbstractEventListener::invokeEventHandler): Ditto.
            * bindings/v8/V8AbstractEventListener.h:
            (WebCore::V8AbstractEventListener::worldContext): Added WorldContextHandle params.
            * bindings/v8/V8EventListenerList.h:
            (WebCore::V8EventListenerList::findOrCreateWrapper): Ditto.
            * bindings/v8/V8LazyEventListener.cpp:
            (WebCore::V8LazyEventListener::V8LazyEventListener): Ditto.
            (WebCore::V8LazyEventListener::prepareListenerObject): Adjusted context retrieval to use WorldContextHandle.
            * bindings/v8/V8LazyEventListener.h:
            (WebCore::V8LazyEventListener::create): Added WorldContextHandle params.
            * bindings/v8/V8Proxy.cpp:
            (WebCore::V8Proxy::context): Refactored to use mainWorldContext();
            (WebCore::V8Proxy::mainWorldContext): Added.
            (WebCore::toV8Context): Changed to use WorldContextHandle.
            * bindings/v8/V8Proxy.h: Added mainWorldContext decl.
            * bindings/v8/V8Utilities.cpp:
            (WebCore::reportException): Added an extra check to avoid crashes during frame teardown.
            * bindings/v8/V8WorkerContextEventListener.cpp:
            (WebCore::V8WorkerContextEventListener::V8WorkerContextEventListener): Added WorldContextHandle params.
            * bindings/v8/V8WorkerContextEventListener.h:
            (WebCore::V8WorkerContextEventListener::create): Added WorldContextHandle params.
            * bindings/v8/WorldContextHandle.cpp: Added.
            * bindings/v8/WorldContextHandle.h: Added.
            * bindings/v8/custom/V8CustomEventListener.cpp:
            (WebCore::V8EventListener::V8EventListener): Added WorldContextHandle params.
            * bindings/v8/custom/V8CustomEventListener.h:
            (WebCore::V8EventListener::create): Added WorldContextHandle params.
    
    LayoutTests:
    
    2009-12-10  Dimitri Glazkov  <dglazkov at chromium.org>
    
            Reviewed by Adam Barth.
    
            [V8] Events created in isolated worlds may fire in main world.
            https://bugs.webkit.org/show_bug.cgi?id=32386
    
            This test is relevant to both JSC and V8 isolated world implementation,
            ensuring that events are fired in the right worlds.
    
            * http/tests/security/isolatedWorld/events.html: Added.
            * http/tests/security/isolatedWorld/events-expected.txt: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51960 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2636bcf..14f7f6c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2009-12-10  Dimitri Glazkov  <dglazkov at chromium.org>
+
+        Reviewed by Adam Barth.
+
+        [V8] Events created in isolated worlds may fire in main world.
+        https://bugs.webkit.org/show_bug.cgi?id=32386
+
+        This test is relevant to both JSC and V8 isolated world implementation,
+        ensuring that events are fired in the right worlds.
+
+        * http/tests/security/isolatedWorld/events.html: Added.
+        * http/tests/security/isolatedWorld/events-expected.txt: Added.
+
 2009-12-10  Patrik Persson  <patrik.j.persson at ericsson.com>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/http/tests/security/isolatedWorld/events-expected.txt b/LayoutTests/http/tests/security/isolatedWorld/events-expected.txt
new file mode 100644
index 0000000..23fd531
--- /dev/null
+++ b/LayoutTests/http/tests/security/isolatedWorld/events-expected.txt
@@ -0,0 +1,5 @@
+
+
+Text attribute event listeners should always fire in main world: PASS
+Function attribute event listeners should fire in the world where they were created: PASS
+XHR attribute event listeners should fire in the world where they were created: PASS
\ No newline at end of file
diff --git a/LayoutTests/http/tests/security/isolatedWorld/events.html b/LayoutTests/http/tests/security/isolatedWorld/events.html
new file mode 100644
index 0000000..0742f9d
--- /dev/null
+++ b/LayoutTests/http/tests/security/isolatedWorld/events.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<title>Test how event handlers work with isolated Worlds</title>
+<script>
+
+// This test is meaningless without layoutTestController.
+if (!window.layoutTestController && !window.eventSender)
+    return;
+
+layoutTestController.dumpAsText();
+layoutTestController.waitUntilDone();
+
+window.textAttributeEventsCount = 0;
+window.xhrEventsCount = 0;
+window.functionAttributeEventsCount = 0;
+window.addEventListener("message", function(message)
+{
+    layoutTestController.notifyDone();
+}, false);
+
+window.textAttributeEventsCallback = function()
+{
+    if (textAttributeEventsCount++)
+        document.getElementById("log").innerHTML += "PASS";
+}
+
+function newTest(title)
+{
+    document.getElementById("log").innerHTML += "<br>" + title + ": ";
+}
+
+function textAttributeEventListener()
+{
+    window.textAttributeEventsCallback = function()
+    {
+        if (window.alreadyFailed)
+            return;
+         document.getElementById("log").innerHTML += "FAIL";
+         window.alreadyFailed = true;
+    }
+
+    var test = document.getElementById("test");
+    test.innerHTML = "<button id='button1' onclick='textAttributeEventsCallback()'></button>";
+    document.getElementById("button1").click();
+}
+
+function functionAttributeEventListener()
+{
+    var test = document.getElementById("test");
+    var button = test.appendChild(document.createElement("button"));
+    window.functionAttributeEventsCount = 0;
+    button.onclick = function()
+    {
+        if (window.functionAttributeEventsCount++)
+            document.getElementById("log").innerHTML += "PASS";
+    }
+    button.style.cssText = "width: 30px;height:30px";
+    button.click();
+}
+
+function xhrEventListener()
+{
+    window.xhrWorld = 1;
+    var done;
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", "anyfile", true);
+    xhr.onreadystatechange = function() {
+        if (done)
+            return;
+        done = true;
+        document.getElementById("log").innerHTML += window.xhrWorld  ? "PASS" : "FAIL";
+        window.postMessage("done", "*");
+    };
+    xhr.send(null);
+}
+
+function runTestInWorld(worldId, funcName)
+{
+    layoutTestController.evaluateScriptInIsolatedWorld(worldId, String(eval(funcName)) + "\n" + funcName + "();");
+}
+
+function runTest() 
+{
+    newTest("Text attribute event listeners should always fire in main world");
+    runTestInWorld(1, "textAttributeEventListener");
+    var button1 = document.getElementById("button1");
+    button1.click();
+    button1.parentElement.removeChild(button1);
+    
+    newTest("Function attribute event listeners should fire in the world where they were created");
+    runTestInWorld(1, "functionAttributeEventListener");
+    var testDiv = document.getElementById("test");
+    // Land somewhere on the button.
+    eventSender.mouseMoveTo(testDiv.offsetLeft + 5, testDiv.offsetTop + 5);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+
+    newTest("XHR attribute event listeners should fire in the world where they were created");
+    runTestInWorld(1, "xhrEventListener");
+}
+
+</script>
+<body onload="runTest()">
+    <div id="test"></div>
+    <div id="log"></div>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d94710a..ee28086 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,47 @@
+2009-12-10  Dimitri Glazkov  <dglazkov at chromium.org>
+
+        Reviewed by Adam Barth.
+
+        [V8] Events created in isolated worlds may fire in main world.
+        https://bugs.webkit.org/show_bug.cgi?id=32386
+
+        Test: http/tests/security/isolatedWorld/events.html
+
+        * WebCore.gypi: Added WorldContextHandle.
+        * bindings/v8/ScriptEventListener.cpp:
+        (WebCore::createAttributeEventListener): Added WorldContextHandle params.
+        * bindings/v8/SharedPersistent.h: Fixed a few style/include issues.
+        * bindings/v8/V8AbstractEventListener.cpp:
+        (WebCore::V8AbstractEventListener::V8AbstractEventListener): Added WorldContextHandle params.
+        (WebCore::V8AbstractEventListener::handleEvent): Adjusted context retrieval to use WorldContextHandle.
+        (WebCore::V8AbstractEventListener::invokeEventHandler): Ditto.
+        * bindings/v8/V8AbstractEventListener.h:
+        (WebCore::V8AbstractEventListener::worldContext): Added WorldContextHandle params.
+        * bindings/v8/V8EventListenerList.h:
+        (WebCore::V8EventListenerList::findOrCreateWrapper): Ditto.
+        * bindings/v8/V8LazyEventListener.cpp:
+        (WebCore::V8LazyEventListener::V8LazyEventListener): Ditto.
+        (WebCore::V8LazyEventListener::prepareListenerObject): Adjusted context retrieval to use WorldContextHandle.
+        * bindings/v8/V8LazyEventListener.h:
+        (WebCore::V8LazyEventListener::create): Added WorldContextHandle params.
+        * bindings/v8/V8Proxy.cpp:
+        (WebCore::V8Proxy::context): Refactored to use mainWorldContext();
+        (WebCore::V8Proxy::mainWorldContext): Added.
+        (WebCore::toV8Context): Changed to use WorldContextHandle.
+        * bindings/v8/V8Proxy.h: Added mainWorldContext decl.
+        * bindings/v8/V8Utilities.cpp:
+        (WebCore::reportException): Added an extra check to avoid crashes during frame teardown.
+        * bindings/v8/V8WorkerContextEventListener.cpp:
+        (WebCore::V8WorkerContextEventListener::V8WorkerContextEventListener): Added WorldContextHandle params.
+        * bindings/v8/V8WorkerContextEventListener.h:
+        (WebCore::V8WorkerContextEventListener::create): Added WorldContextHandle params.
+        * bindings/v8/WorldContextHandle.cpp: Added.
+        * bindings/v8/WorldContextHandle.h: Added.
+        * bindings/v8/custom/V8CustomEventListener.cpp:
+        (WebCore::V8EventListener::V8EventListener): Added WorldContextHandle params.
+        * bindings/v8/custom/V8CustomEventListener.h:
+        (WebCore::V8EventListener::create): Added WorldContextHandle params.
+
 2009-12-10  Jon Honeycutt  <jhoneycutt at apple.com>
 
         Pass more information about a plug-in to the PluginHalterDelegate
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index d22cf48..4a37c79 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -838,6 +838,8 @@
             'bindings/v8/WorkerContextExecutionProxy.cpp',
             'bindings/v8/WorkerScriptController.h',
             'bindings/v8/WorkerScriptController.cpp',
+            'bindings/v8/WorldContextHandle.cpp',
+            'bindings/v8/WorldContextHandle.h',
             'bindings/v8/npruntime.cpp',
             'bindings/v8/npruntime_impl.h',
             'bindings/v8/npruntime_internal.h',
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index 03713be..51d53ab 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -68,7 +68,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
         sourceURL = node->document()->url().string();
     }
 
-    return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber);
+    return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
 }
 
 PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr)
@@ -95,7 +95,7 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
         columnNumber = frame->document()->tokenizer()->columnNumber();
     }
     sourceURL = frame->document()->url().string();
-    return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber);
+    return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
 }
 
 String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* listener)
diff --git a/WebCore/bindings/v8/SharedPersistent.h b/WebCore/bindings/v8/SharedPersistent.h
index c1232ae..8825bd5 100644
--- a/WebCore/bindings/v8/SharedPersistent.h
+++ b/WebCore/bindings/v8/SharedPersistent.h
@@ -32,6 +32,8 @@
 #define SharedPersistent_h
 
 #include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
 
 namespace WebCore {
 
@@ -40,7 +42,7 @@ namespace WebCore {
     // object and when it should no longer be accessible the object's
     // owner can clear it.
     template <typename T>
-    class SharedPersistent : public WTF::RefCounted<SharedPersistent<T> > {
+    class SharedPersistent : public RefCounted<SharedPersistent<T> > {
     public:
         void set(v8::Persistent<T> value)
         {
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index fa462ad..0f5b5c8 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -50,10 +50,11 @@ static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter
     listener->disposeListenerObject();
 }
 
-V8AbstractEventListener::V8AbstractEventListener(bool isAttribute)
+V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext)
     : EventListener(JSEventListenerType)
     , m_isWeak(true)
     , m_isAttribute(isAttribute)
+    , m_worldContext(worldContext)
 {
 }
 
@@ -75,7 +76,7 @@ void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event
 
     v8::HandleScope handleScope;
 
-    v8::Local<v8::Context> v8Context = toV8Context(context);
+    v8::Local<v8::Context> v8Context = toV8Context(context, worldContext());
     if (v8Context.IsEmpty())
         return;
 
@@ -115,7 +116,7 @@ void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener)
 void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context, Event* event, v8::Handle<v8::Value> jsEvent)
 {
 
-    v8::Local<v8::Context> v8Context = toV8Context(context);
+    v8::Local<v8::Context> v8Context = toV8Context(context, worldContext());
     if (v8Context.IsEmpty())
         return;
 
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
index 695c667..0afbed5 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.h
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -32,8 +32,8 @@
 #define V8AbstractEventListener_h
 
 #include "EventListener.h"
-#include "OwnHandle.h"
-#include "SharedPersistent.h"
+#include "WorldContextHandle.h"
+
 #include <v8.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -97,7 +97,7 @@ namespace WebCore {
         void disposeListenerObject();
 
     protected:
-        V8AbstractEventListener(bool isAttribute);
+        V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext);
 
         virtual void prepareListenerObject(ScriptExecutionContext*) { }
 
@@ -107,6 +107,9 @@ namespace WebCore {
 
         // Get the receiver object to use for event listener call.
         v8::Local<v8::Object> getReceiverObject(Event*);
+
+        const WorldContextHandle& worldContext() const { return m_worldContext; }
+
     private:
         // Implementation of EventListener function.
         virtual bool virtualisAttribute() const { return m_isAttribute; }
@@ -120,6 +123,8 @@ namespace WebCore {
 
         // Indicates if this is an HTML type listener.
         bool m_isAttribute;
+
+        WorldContextHandle m_worldContext;
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h
index 6e6a1e4..fdf211d 100644
--- a/WebCore/bindings/v8/V8EventListenerList.h
+++ b/WebCore/bindings/v8/V8EventListenerList.h
@@ -31,15 +31,14 @@
 #ifndef V8EventListenerList_h
 #define V8EventListenerList_h
 
-#include <v8.h>
-
-#include "PassRefPtr.h"
 #include "V8CustomEventListener.h"
 #include "V8HiddenPropertyName.h"
 
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
 namespace WebCore {
     class Frame;
-    class V8EventListener;
 
     // This is a container for V8EventListener objects that uses hidden properties of v8::Object to speed up lookups.
     class V8EventListenerList {
@@ -94,7 +93,7 @@ namespace WebCore {
         if (wrapper)
             return wrapper;
 
-        PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute);
+        PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, WorldContextHandle(UseCurrentWorld));
         if (wrapperPtr)
             object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get()));
 
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
index 88c75d1..16b21d6 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.cpp
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -35,13 +35,14 @@
 #include "V8Binding.h"
 #include "V8HiddenPropertyName.h"
 #include "V8Proxy.h"
+#include "WorldContextHandle.h"
 
 #include <wtf/StdLibExtras.h>
 
 namespace WebCore {
 
-V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber)
-    : V8AbstractEventListener(true)
+V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
+    : V8AbstractEventListener(true, worldContext)
     , m_functionName(functionName)
     , m_isSVGEvent(isSVGEvent)
     , m_code(code)
@@ -83,7 +84,7 @@ void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context)
         return;
 
     // Use the outer scope to hold context.
-    v8::Handle<v8::Context> v8Context = proxy->context();
+    v8::Local<v8::Context> v8Context = worldContext().adjustedContext(proxy);
     // Bail out if we cannot get the context.
     if (v8Context.IsEmpty())
         return;
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index 699460b..078dcf1 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -45,9 +45,9 @@ namespace WebCore {
     // A V8LazyEventListener is always a HTML event handler.
     class V8LazyEventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber)
+        static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
         {
-            return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber));
+            return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber, worldContext));
         }
 
         virtual bool isLazy() const { return true; }
@@ -56,7 +56,7 @@ namespace WebCore {
         virtual void prepareListenerObject(ScriptExecutionContext*);
 
     private:
-        V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber);
+        V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext);
 
         virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
 
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 1c57774..e4ee99f 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -1207,8 +1207,13 @@ v8::Local<v8::Context> V8Proxy::context()
             return v8::Local<v8::Context>();
         return v8::Local<v8::Context>::New(context->get());
     }
+    return mainWorldContext();
+}
+
+v8::Local<v8::Context> V8Proxy::mainWorldContext()
+{
     initContextIfNeeded();
-    return v8::Local<v8::Context>::New(m_context);;
+    return v8::Local<v8::Context>::New(m_context);
 }
 
 v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
@@ -1217,8 +1222,7 @@ v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
     if (!proxy)
         return v8::Local<v8::Context>();
 
-    proxy->initContextIfNeeded();
-    return v8::Local<v8::Context>::New(proxy->m_context);
+    return proxy->mainWorldContext();
 }
 
 v8::Local<v8::Context> V8Proxy::currentContext()
@@ -1404,11 +1408,11 @@ void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
     context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
 }
 
-v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context)
+v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context, const WorldContextHandle& worldContext)
 {
     if (context->isDocument()) {
         if (V8Proxy* proxy = V8Proxy::retrieve(context))
-            return proxy->context();
+            return worldContext.adjustedContext(proxy);
     } else if (context->isWorkerContext()) {
         if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy())
             return proxy->context();
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index ab351af..b1fdb80 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -59,6 +59,7 @@ namespace WebCore {
     class String;
     class V8EventListener;
     class V8IsolatedWorld;
+    class WorldContextHandle;
 
     // FIXME: use standard logging facilities in WebCore.
     void logInfo(Frame*, const String& message, const String& url);
@@ -339,6 +340,7 @@ namespace WebCore {
         static bool sourceName(String& result);
 
         v8::Local<v8::Context> context();
+        v8::Local<v8::Context> mainWorldContext();
 
         bool setContextDebugId(int id);
         static int contextDebugId(v8::Handle<v8::Context>);
@@ -478,7 +480,7 @@ namespace WebCore {
     }
 
 
-    v8::Local<v8::Context> toV8Context(ScriptExecutionContext*);
+    v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, const WorldContextHandle& worldContext);
 
     // Used by an interceptor callback that it hasn't found anything to
     // intercept.
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index 0373aee..c547cc7 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -168,7 +168,8 @@ void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher)
     // Do not report the exception if the current execution context is Document because we do not want to lead to duplicate error messages in the console.
     // FIXME (31171): need better design to solve the duplicate error message reporting problem.
     ScriptExecutionContext* context = getScriptExecutionContext(scriptState);
-    if (!context->isDocument())
+    // During the frame teardown, there may not be a valid context.
+    if (context && !context->isDocument())
       context->reportException(errorMessage, lineNumber, sourceURL);
     exceptionCatcher.Reset();
 }
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index 8f1514d..e5356de 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -48,8 +48,8 @@ static WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context)
     return workerContext->script()->proxy();
 }
 
-V8WorkerContextEventListener::V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline)
-    : V8EventListener(listener, isInline)
+V8WorkerContextEventListener::V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+    : V8EventListener(listener, isInline, worldContext)
 {
 }
 
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index 68be1e3..4487497 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -44,16 +44,16 @@ namespace WebCore {
 
     class V8WorkerContextEventListener : public V8EventListener {
     public:
-        static PassRefPtr<V8WorkerContextEventListener> create(v8::Local<v8::Object> listener, bool isInline)
+        static PassRefPtr<V8WorkerContextEventListener> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
         {
-            return adoptRef(new V8WorkerContextEventListener(listener, isInline));
+            return adoptRef(new V8WorkerContextEventListener(listener, isInline, worldContext));
         }
 
         virtual void handleEvent(ScriptExecutionContext*, Event*);
         virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
 
     private:
-        V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline);
+        V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
 
         virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
         v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*);
diff --git a/WebCore/bindings/v8/WorldContextHandle.cpp b/WebCore/bindings/v8/WorldContextHandle.cpp
new file mode 100644
index 0000000..eb83586
--- /dev/null
+++ b/WebCore/bindings/v8/WorldContextHandle.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorldContextHandle.h"
+
+#include "V8IsolatedWorld.h"
+
+namespace WebCore {
+
+WorldContextHandle::WorldContextHandle(WorldToUse worldToUse)
+    : m_worldToUse(worldToUse)
+{
+    if (worldToUse == UseMainWorld)
+        return;
+
+    if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered())
+        m_context = world->sharedContext();
+}
+
+v8::Local<v8::Context> WorldContextHandle::adjustedContext(V8Proxy* proxy) const
+{
+    if (m_worldToUse == UseMainWorld)
+        return proxy->mainWorldContext();
+    if (!m_context || m_context->get().IsEmpty())
+        return proxy->context();
+    return v8::Local<v8::Context>::New(m_context->get());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/WorldContextHandle.h b/WebCore/bindings/v8/WorldContextHandle.h
new file mode 100644
index 0000000..ad0983e
--- /dev/null
+++ b/WebCore/bindings/v8/WorldContextHandle.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorldContextHandle_h
+#define WorldContextHandle_h
+
+#include "SharedPersistent.h"
+
+#include <v8.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class V8Proxy;
+
+enum WorldToUse { UseMainWorld, UseCurrentWorld };
+
+class WorldContextHandle {
+public:
+    WorldContextHandle(WorldToUse);
+    v8::Local<v8::Context> adjustedContext(V8Proxy*) const;
+
+private:
+    WorldToUse m_worldToUse;
+    RefPtr<SharedPersistent<v8::Context> > m_context;
+};
+
+} // namespace WebCore
+
+#endif // WorldContextHandle_h
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
index 350424f..24d752f 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -35,8 +35,8 @@
 
 namespace WebCore {
 
-V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute)
-    : V8AbstractEventListener(isAttribute)
+V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext)
+    : V8AbstractEventListener(isAttribute, worldContext)
 {
     setListenerObject(listener);
 }
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h
index ca029a1..f9d5385 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.h
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h
@@ -44,13 +44,13 @@ namespace WebCore {
     // that can handle the event.
     class V8EventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute)
+        static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext)
         {
-            return adoptRef(new V8EventListener(listener, isAttribute));
+            return adoptRef(new V8EventListener(listener, isAttribute, worldContext));
         }
 
     protected:
-        V8EventListener(v8::Local<v8::Object> listener, bool isAttribute);
+        V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext);
 
         v8::Local<v8::Function> getListenerFunction(ScriptExecutionContext*);
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list