Changeset 34109 in webkit


Ignore:
Timestamp:
May 24, 2008 6:01:35 PM (16 years ago)
Author:
timothy@apple.com
Message:

Fixes a crash where a new Inspector would get an old
JSInspectedObjectWrapper for a user agent CSSStyleDeclaration.
Since these style objects shared between pages, the wrapper cache
would have a wrapper for the object still. But the wrapper was
for a previous global object and with a disconnected frame. This
fixes the wrapper cache so wrappers are remembered per global object
and the object they are wrapping.

<rdar://problem/5958567> repro crash in WebCore::Frame::keepAlive()
opening inspector window after closing it

Reviewed by Darin Adler.

  • bindings/js/JSInspectedObjectWrapper.cpp:

(WebCore::wrappers): Return a GlobalObjectWrapperMap reference.
(WebCore::JSInspectedObjectWrapper::wrap): Find the WrapperMap
by the dynamicGlobalObject then find the wrapper for unwrappedObject.
(WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper): Changes
how the wrapper is added to the wrapper cache.
(WebCore::JSInspectedObjectWrapper::~JSInspectedObjectWrapper): Changes
how the wrapper is removed from the wrapper cache.

  • bindings/js/JSQuarantinedObjectWrapper.h:

(WebCore::JSQuarantinedObjectWrapper:unwrappedGlobalObject): Added.

Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r34108 r34109  
     12008-05-24  Timothy Hatcher  <timothy@apple.com>
     2
     3        Fixes a crash where a new Inspector would get an old
     4        JSInspectedObjectWrapper for a user agent CSSStyleDeclaration.
     5        Since these style objects shared between pages, the wrapper cache
     6        would have a wrapper for the object still. But the wrapper was
     7        for a previous global object and with a disconnected frame. This
     8        fixes the wrapper cache so wrappers are remembered per global object
     9        and the object they are wrapping.
     10
     11        <rdar://problem/5958567> repro crash in WebCore::Frame::keepAlive()
     12        opening inspector window after closing it
     13
     14        Reviewed by Darin Adler.
     15
     16        * bindings/js/JSInspectedObjectWrapper.cpp:
     17        (WebCore::wrappers): Return a GlobalObjectWrapperMap reference.
     18        (WebCore::JSInspectedObjectWrapper::wrap): Find the WrapperMap
     19        by the dynamicGlobalObject then find the wrapper for unwrappedObject.
     20        (WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper): Changes
     21        how the wrapper is added to the wrapper cache.
     22        (WebCore::JSInspectedObjectWrapper::~JSInspectedObjectWrapper): Changes
     23        how the wrapper is removed from the wrapper cache.
     24        * bindings/js/JSQuarantinedObjectWrapper.h:
     25        (WebCore::JSQuarantinedObjectWrapper:unwrappedGlobalObject): Added.
     26
    1272008-05-24  Alexey Proskuryakov  <ap@webkit.org>
    228
  • trunk/WebCore/bindings/js/JSInspectedObjectWrapper.cpp

    r33414 r34109  
    3434
    3535typedef HashMap<JSObject*, JSInspectedObjectWrapper*> WrapperMap;
     36typedef HashMap<JSGlobalObject*, WrapperMap*> GlobalObjectWrapperMap;
    3637
    37 static WrapperMap& wrappers()
     38static GlobalObjectWrapperMap& wrappers()
    3839{
    39     static WrapperMap map;
     40    static GlobalObjectWrapperMap map;
    4041    return map;
    4142}
     
    5354        return unwrappedObject;
    5455
    55     if (JSInspectedObjectWrapper* wrapper = wrappers().get(unwrappedObject))
    56         return wrapper;
     56    if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->dynamicGlobalObject()))
     57        if (JSInspectedObjectWrapper* wrapper = wrapperMap->get(unwrappedObject))
     58            return wrapper;
    5759
    5860    JSValue* prototype = unwrappedObject->prototype();
     
    6567    : JSQuarantinedObjectWrapper(unwrappedExec, unwrappedObject, wrappedPrototype)
    6668{
    67     ASSERT(!wrappers().contains(unwrappedObject));
    68     wrappers().set(unwrappedObject, this);
     69    WrapperMap* wrapperMap = wrappers().get(unwrappedGlobalObject());
     70    if (!wrapperMap) {
     71        wrapperMap = new WrapperMap;
     72        wrappers().set(unwrappedGlobalObject(), wrapperMap);
     73    }
     74
     75    ASSERT(!wrapperMap->contains(unwrappedObject));
     76    wrapperMap->set(unwrappedObject, this);
    6977}
    7078
    7179JSInspectedObjectWrapper::~JSInspectedObjectWrapper()
    7280{
    73     wrappers().remove(unwrappedObject());
     81    ASSERT(wrappers().contains(unwrappedGlobalObject()));
     82    WrapperMap* wrapperMap = wrappers().get(unwrappedGlobalObject());
     83
     84    ASSERT(wrapperMap->contains(unwrappedObject()));
     85    wrapperMap->remove(unwrappedObject());
     86
     87    if (wrapperMap->isEmpty()) {
     88        wrappers().remove(unwrappedGlobalObject());
     89        delete wrapperMap;
     90    }
    7491}
    7592
  • trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.h

    r33979 r34109  
    3838
    3939        KJS::JSObject* unwrappedObject() const { return m_unwrappedObject; }
     40        KJS::JSGlobalObject* unwrappedGlobalObject() const { return m_unwrappedGlobalObject; };
    4041        KJS::ExecState* unwrappedExecState() const;
    4142
Note: See TracChangeset for help on using the changeset viewer.