Changeset 60840 in webkit


Ignore:
Timestamp:
Jun 8, 2010 5:29:05 AM (14 years ago)
Author:
steveblock@google.com
Message:

Prevent Geolocation making callbacks to a ScriptExecutionContext that no longer exists
https://bugs.webkit.org/show_bug.cgi?id=40162

Reviewed by Jeremy Orlow.

WebCore:

Before making callbacks, we check that the relevant ScriptExecutionContext still exists.
To achieve this, the callbacks inherit from ActiveDOMObject.

The ScriptExecutionContext is ref'ed from script, so may not be GC'ed for some time after
it is disconnected from its frame. Making the callback currently involves accessing the
Frame, so an additional check for the Frame is required.

This change also prevents the V8 bindings from incorrectly holding a reference to the Frame.

Test: fast/dom/Geolocation/callback-to-deleted-context.html

  • bindings/js/JSCallbackData.cpp:

(WebCore::JSCallbackData::invokeCallback):

  • bindings/js/JSCustomPositionCallback.cpp:

(WebCore::JSCustomPositionCallback::JSCustomPositionCallback):
(WebCore::JSCustomPositionCallback::handleEvent):

  • bindings/js/JSCustomPositionErrorCallback.cpp:

(WebCore::JSCustomPositionErrorCallback::JSCustomPositionErrorCallback):
(WebCore::JSCustomPositionErrorCallback::handleEvent):

  • bindings/v8/custom/V8CustomPositionCallback.cpp:

(WebCore::V8CustomPositionCallback::V8CustomPositionCallback):
(WebCore::V8CustomPositionCallback::handleEvent):

  • bindings/v8/custom/V8CustomPositionCallback.h:

(WebCore::V8CustomPositionCallback::create):

  • bindings/v8/custom/V8CustomPositionErrorCallback.cpp:

(WebCore::V8CustomPositionErrorCallback::V8CustomPositionErrorCallback):
(WebCore::V8CustomPositionErrorCallback::handleEvent):

  • bindings/v8/custom/V8CustomPositionErrorCallback.h:

(WebCore::V8CustomPositionErrorCallback::create):

  • bindings/v8/custom/V8GeolocationCustom.cpp:

(WebCore::createPositionCallback):
(WebCore::createPositionErrorCallback):

  • page/PositionCallback.h:

(WebCore::PositionCallback::PositionCallback):

  • page/PositionErrorCallback.h:

(WebCore::PositionErrorCallback::PositionErrorCallback):

LayoutTests:

  • fast/dom/Geolocation/callback-to-deleted-context-expected.txt: Added.
  • fast/dom/Geolocation/callback-to-deleted-context.html: Added.
  • fast/dom/Geolocation/resources/callback-to-deleted-context-inner1.html: Added.
  • fast/dom/Geolocation/resources/callback-to-deleted-context-inner2.html: Added.
  • fast/dom/Geolocation/script-tests/callback-to-deleted-context.js: Added.
  • platform/gtk/Skipped: Modified.
Location:
trunk
Files:
5 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r60839 r60840  
     12010-06-08  Steve Block  <steveblock@google.com>
     2
     3        Reviewed by Jeremy Orlow.
     4
     5        Prevent Geolocation making callbacks to a ScriptExecutionContext that no longer exists
     6        https://bugs.webkit.org/show_bug.cgi?id=40162
     7
     8        * fast/dom/Geolocation/callback-to-deleted-context-expected.txt: Added.
     9        * fast/dom/Geolocation/callback-to-deleted-context.html: Added.
     10        * fast/dom/Geolocation/resources/callback-to-deleted-context-inner1.html: Added.
     11        * fast/dom/Geolocation/resources/callback-to-deleted-context-inner2.html: Added.
     12        * fast/dom/Geolocation/script-tests/callback-to-deleted-context.js: Added.
     13        * platform/gtk/Skipped: Modified.
     14
    1152010-06-08  Steve Block  <steveblock@google.com>
    216
  • trunk/LayoutTests/platform/gtk/Skipped

    r60839 r60840  
    59175917fast/dom/Geolocation/callback-to-remote-context.html
    59185918fast/dom/Geolocation/callback-to-remote-context2.html
     5919fast/dom/Geolocation/callback-to-deleted-context.html
    59195920
    59205921# https://bugs.webkit.org/show_bug.cgi?id=40269
  • trunk/WebCore/ChangeLog

    r60835 r60840  
     12010-06-08  Steve Block  <steveblock@google.com>
     2
     3        Reviewed by Jeremy Orlow.
     4
     5        Prevent Geolocation making callbacks to a ScriptExecutionContext that no longer exists
     6        https://bugs.webkit.org/show_bug.cgi?id=40162
     7
     8        Before making callbacks, we check that the relevant ScriptExecutionContext still exists.
     9        To achieve this, the callbacks inherit from ActiveDOMObject.
     10
     11        The ScriptExecutionContext is ref'ed from script, so may not be GC'ed for some time after
     12        it is disconnected from its frame. Making the callback currently involves accessing the
     13        Frame, so an additional check for the Frame is required.
     14
     15        This change also prevents the V8 bindings from incorrectly holding a reference to the Frame.
     16
     17        Test: fast/dom/Geolocation/callback-to-deleted-context.html
     18
     19        * bindings/js/JSCallbackData.cpp:
     20        (WebCore::JSCallbackData::invokeCallback):
     21        * bindings/js/JSCustomPositionCallback.cpp:
     22        (WebCore::JSCustomPositionCallback::JSCustomPositionCallback):
     23        (WebCore::JSCustomPositionCallback::handleEvent):
     24        * bindings/js/JSCustomPositionErrorCallback.cpp:
     25        (WebCore::JSCustomPositionErrorCallback::JSCustomPositionErrorCallback):
     26        (WebCore::JSCustomPositionErrorCallback::handleEvent):
     27        * bindings/v8/custom/V8CustomPositionCallback.cpp:
     28        (WebCore::V8CustomPositionCallback::V8CustomPositionCallback):
     29        (WebCore::V8CustomPositionCallback::handleEvent):
     30        * bindings/v8/custom/V8CustomPositionCallback.h:
     31        (WebCore::V8CustomPositionCallback::create):
     32        * bindings/v8/custom/V8CustomPositionErrorCallback.cpp:
     33        (WebCore::V8CustomPositionErrorCallback::V8CustomPositionErrorCallback):
     34        (WebCore::V8CustomPositionErrorCallback::handleEvent):
     35        * bindings/v8/custom/V8CustomPositionErrorCallback.h:
     36        (WebCore::V8CustomPositionErrorCallback::create):
     37        * bindings/v8/custom/V8GeolocationCustom.cpp:
     38        (WebCore::createPositionCallback):
     39        (WebCore::createPositionErrorCallback):
     40        * page/PositionCallback.h:
     41        (WebCore::PositionCallback::PositionCallback):
     42        * page/PositionErrorCallback.h:
     43        (WebCore::PositionErrorCallback::PositionErrorCallback):
     44
    1452010-06-08  Xan Lopez  <xlopez@igalia.com>
    246
  • trunk/WebCore/bindings/js/JSCallbackData.cpp

    r60631 r60840  
    6161   
    6262    globalObject()->globalData()->timeoutChecker.start();
    63     JSValue result = globalObject()->scriptExecutionContext()->isDocument()
     63    ScriptExecutionContext* context = globalObject()->scriptExecutionContext();
     64    // We will fail to get the context if the frame has been detached.
     65    if (!context)
     66        return JSValue();
     67
     68    JSValue result = context->isDocument()
    6469        ? JSMainThreadExecState::call(exec, function, callType, callData, callback(), args)
    6570        : JSC::call(exec, function, callType, callData, callback(), args);
  • trunk/WebCore/bindings/js/JSCustomPositionCallback.cpp

    r56781 r60840  
    3939
    4040JSCustomPositionCallback::JSCustomPositionCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
    41     : m_data(callback, globalObject)
     41    : PositionCallback(globalObject->scriptExecutionContext())
     42    , m_data(callback, globalObject)
    4243{
    4344}
     
    4546void JSCustomPositionCallback::handleEvent(Geoposition* geoposition)
    4647{
     48    // ActiveDOMObject will null our pointer to the ScriptExecutionContext when it goes away.
     49    if (!scriptExecutionContext())
     50        return;
     51
    4752    RefPtr<JSCustomPositionCallback> protect(this);
    4853
  • trunk/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp

    r56781 r60840  
    3939
    4040JSCustomPositionErrorCallback::JSCustomPositionErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
    41     : m_data(callback, globalObject)
     41    : PositionErrorCallback(globalObject->scriptExecutionContext())
     42    , m_data(callback, globalObject)
    4243{
    4344}
     
    4546void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
    4647{
     48    // ActiveDOMObject will null our pointer to the ScriptExecutionContext when it goes away.
     49    if (!scriptExecutionContext())
     50        return;
     51
    4752    RefPtr<JSCustomPositionErrorCallback> protect(this);
    4853
  • trunk/WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp

    r60330 r60840  
    2727#include "V8CustomPositionCallback.h"
    2828
    29 #include "Frame.h"
     29#include "ScriptExecutionContext.h"
    3030#include "V8CustomVoidCallback.h"  // For invokeCallback
    3131#include "V8Geoposition.h"
     32#include "V8Proxy.h"
    3233
    3334namespace WebCore {
    3435
    35 V8CustomPositionCallback::V8CustomPositionCallback(v8::Local<v8::Object> callback, Frame* frame)
    36     : m_callback(v8::Persistent<v8::Object>::New(callback))
    37     , m_frame(frame)
     36V8CustomPositionCallback::V8CustomPositionCallback(v8::Local<v8::Object> callback, ScriptExecutionContext* context)
     37    : PositionCallback(context)
     38    , m_callback(v8::Persistent<v8::Object>::New(callback))
    3839{
    3940}
     
    4849    v8::HandleScope handleScope;
    4950
    50     v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
     51    // ActiveDOMObject will null our pointer to the ScriptExecutionContext when it goes away.
     52    ScriptExecutionContext* scriptContext = scriptExecutionContext();
     53    if (!scriptContext)
     54        return;
     55
     56    // The lookup of the proxy will fail if the Frame has been detached.
     57    V8Proxy* proxy = V8Proxy::retrieve(scriptContext);
     58    if (!proxy)
     59        return;
     60
     61    v8::Handle<v8::Context> context = proxy->context();
    5162    if (context.IsEmpty())
    5263        return;
     
    5869    };
    5970
    60     // Protect the frame until the callback returns.
    61     RefPtr<Frame> protector(m_frame);
     71    // Protect the script context until the callback returns.
     72    RefPtr<ScriptExecutionContext> protector(scriptContext);
    6273
    6374    bool callbackReturnValue = false;
    64     invokeCallback(m_callback, 1, argv, callbackReturnValue, m_frame->document());
     75    invokeCallback(m_callback, 1, argv, callbackReturnValue, scriptContext);
    6576}
    6677
  • trunk/WebCore/bindings/v8/custom/V8CustomPositionCallback.h

    r51540 r60840  
    2828
    2929#include "PositionCallback.h"
     30
    3031#include <v8.h>
    3132#include <wtf/PassRefPtr.h>
     
    3637class Frame;
    3738class Geoposition;
     39class ScriptExecutionContext;
    3840
    3941class V8CustomPositionCallback : public PositionCallback {
    4042public:
    41     static PassRefPtr<V8CustomPositionCallback> create(v8::Local<v8::Value> value, Frame* frame)
     43    static PassRefPtr<V8CustomPositionCallback> create(v8::Local<v8::Value> value, ScriptExecutionContext* context)
    4244    {
    4345        ASSERT(value->IsObject());
    44         return adoptRef(new V8CustomPositionCallback(value->ToObject(), frame));
     46        return adoptRef(new V8CustomPositionCallback(value->ToObject(), context));
    4547    }
    4648    virtual ~V8CustomPositionCallback();
     
    4951
    5052private:
    51     V8CustomPositionCallback(v8::Local<v8::Object>, Frame*);
     53    V8CustomPositionCallback(v8::Local<v8::Object>, ScriptExecutionContext*);
    5254
    5355    v8::Persistent<v8::Object> m_callback;
    54     RefPtr<Frame> m_frame;
    5556};
    5657
  • trunk/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp

    r60330 r60840  
    2727#include "V8CustomPositionErrorCallback.h"
    2828
    29 #include "Frame.h"
     29#include "ScriptExecutionContext.h"
    3030#include "V8CustomVoidCallback.h"  // For invokeCallback
    3131#include "V8PositionError.h"
     32#include "V8Proxy.h"
    3233
    3334namespace WebCore {
    3435
    35 V8CustomPositionErrorCallback::V8CustomPositionErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
    36     : m_callback(v8::Persistent<v8::Object>::New(callback))
    37     , m_frame(frame)
     36V8CustomPositionErrorCallback::V8CustomPositionErrorCallback(v8::Local<v8::Object> callback, ScriptExecutionContext* context)
     37    : PositionErrorCallback(context)
     38    , m_callback(v8::Persistent<v8::Object>::New(callback))
    3839{
    3940}
     
    4849    v8::HandleScope handleScope;
    4950
    50     v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
     51    // ActiveDOMObject will null our pointer to the ScriptExecutionContext when it goes away.
     52    ScriptExecutionContext* scriptContext = scriptExecutionContext();
     53    if (!scriptContext)
     54        return;
     55
     56    // The lookup of the proxy will fail if the Frame has been detached.
     57    V8Proxy* proxy = V8Proxy::retrieve(scriptContext);
     58    if (!proxy)
     59        return;
     60
     61    v8::Handle<v8::Context> context = proxy->context();
    5162    if (context.IsEmpty())
    5263        return;
     
    5869    };
    5970
    60     // Protect the frame until the callback returns.
    61     RefPtr<Frame> protector(m_frame);
     71    // Protect the script context until the callback returns.
     72    RefPtr<ScriptExecutionContext> protector(scriptContext);
    6273
    6374    bool callbackReturnValue = false;
    64     invokeCallback(m_callback, 1, argv, callbackReturnValue, m_frame->document());
     75    invokeCallback(m_callback, 1, argv, callbackReturnValue, scriptContext);
    6576}
    6677
  • trunk/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h

    r51540 r60840  
    2828
    2929#include "PositionErrorCallback.h"
     30
    3031#include <v8.h>
    3132#include <wtf/PassRefPtr.h>
     
    3637class Frame;
    3738class PositionError;
     39class ScriptExecutionContext;
    3840
    3941class V8CustomPositionErrorCallback : public PositionErrorCallback {
    4042public:
    41     static PassRefPtr<V8CustomPositionErrorCallback> create(v8::Local<v8::Value> value, Frame* frame)
     43    static PassRefPtr<V8CustomPositionErrorCallback> create(v8::Local<v8::Value> value, ScriptExecutionContext* context)
    4244    {
    4345        ASSERT(value->IsObject());
    44         return adoptRef(new V8CustomPositionErrorCallback(value->ToObject(), frame));
     46        return adoptRef(new V8CustomPositionErrorCallback(value->ToObject(), context));
    4547    }
    4648    virtual ~V8CustomPositionErrorCallback();
     
    4951
    5052private:
    51     V8CustomPositionErrorCallback(v8::Local<v8::Object>, Frame*);
     53    V8CustomPositionErrorCallback(v8::Local<v8::Object>, ScriptExecutionContext*);
    5254
    5355    v8::Persistent<v8::Object> m_callback;
    54     RefPtr<Frame> m_frame;
    5556};
    5657
  • trunk/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp

    r54349 r60840  
    2727#include "V8Geolocation.h"
    2828
     29#include "Frame.h"
    2930#include "Geolocation.h"
    30 
    3131#include "V8Binding.h"
    3232#include "V8CustomPositionCallback.h"
     
    5757    }
    5858
    59     Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    60     return V8CustomPositionCallback::create(value, frame);
     59    return V8CustomPositionCallback::create(value, getScriptExecutionContext());
    6160}
    6261
     
    7675    }
    7776
    78     Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
    79     return V8CustomPositionErrorCallback::create(value, frame);
     77    return V8CustomPositionErrorCallback::create(value, getScriptExecutionContext());
    8078}
    8179
  • trunk/WebCore/page/PositionCallback.h

    r55633 r60840  
    2727#define PositionCallback_h
    2828
     29#include "ActiveDOMObject.h"
    2930#include <wtf/RefCounted.h>
    3031
     
    3334    class Geoposition;
    3435   
    35     class PositionCallback : public RefCounted<PositionCallback> {
     36    class PositionCallback : public RefCounted<PositionCallback>, public ActiveDOMObject {
    3637    public:
     38        PositionCallback(ScriptExecutionContext* context) : ActiveDOMObject(context, this) { }
    3739        virtual ~PositionCallback() { }
    3840        virtual void handleEvent(Geoposition*) = 0;
  • trunk/WebCore/page/PositionErrorCallback.h

    r55633 r60840  
    2727#define PositionErrorCallback_h
    2828
     29#include "ActiveDOMObject.h"
    2930#include <wtf/RefCounted.h>
    3031
     
    3334    class PositionError;
    3435
    35     class PositionErrorCallback : public RefCounted<PositionErrorCallback> {
     36    class PositionErrorCallback : public RefCounted<PositionErrorCallback>, public ActiveDOMObject {
    3637    public:
     38        PositionErrorCallback(ScriptExecutionContext* context) : ActiveDOMObject(context, this) { }
    3739        virtual ~PositionErrorCallback() { }
    3840        virtual void handleEvent(PositionError*) = 0;
Note: See TracChangeset for help on using the changeset viewer.