Commit 1e08db84 authored by haraken@chromium.org's avatar haraken@chromium.org

Revert 181758 "Simplify DOMWindowProperty and its unregistration."

This CL caused use-after-free in :LocalDOMWindow::willDetachDocumentFromFrame.
https://code.google.com/p/chromium/issues/detail?id=413316

> Simplify DOMWindowProperty and its unregistration.
> 
> As LocalDOMWindow controls the registration lifetime of its
> DOMWindowProperties, there's no need to offer a separate unregistration
> mechanism. Remove it, simplify notification code + retire now unused
> LocalDOMWindow back reference on DOMWindowProperty.
> 
> R=haraken,ager
> BUG=
> 
> Review URL: https://codereview.chromium.org/558213002

TBR=sigbjornf@opera.com

Review URL: https://codereview.chromium.org/564013002

git-svn-id: svn://svn.chromium.org/blink/trunk@181867 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 0763169e
...@@ -34,24 +34,39 @@ namespace blink { ...@@ -34,24 +34,39 @@ namespace blink {
DOMWindowProperty::DOMWindowProperty(LocalFrame* frame) DOMWindowProperty::DOMWindowProperty(LocalFrame* frame)
: m_frame(frame) : m_frame(frame)
, m_associatedDOMWindow(nullptr)
{ {
// FIXME: For now it *is* acceptable for a DOMWindowProperty to be created with a null frame. // FIXME: For now it *is* acceptable for a DOMWindowProperty to be created with a null frame.
// See fast/dom/navigator-detached-no-crash.html for the recipe. // See fast/dom/navigator-detached-no-crash.html for the recipe.
// We should fix that. <rdar://problem/11567132> // We should fix that. <rdar://problem/11567132>
if (m_frame) if (m_frame) {
m_frame->domWindow()->registerProperty(this); m_associatedDOMWindow = m_frame->domWindow();
m_associatedDOMWindow->registerProperty(this);
}
} }
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DOMWindowProperty); #if !ENABLE(OILPAN)
DOMWindowProperty::~DOMWindowProperty()
{
if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
m_associatedDOMWindow = nullptr;
m_frame = nullptr;
}
#endif
void DOMWindowProperty::willDestroyGlobalObjectInFrame() void DOMWindowProperty::willDestroyGlobalObjectInFrame()
{ {
// If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them. // If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them.
ASSERT(m_frame); ASSERT(m_frame);
ASSERT(m_associatedDOMWindow);
// DOMWindowProperty's registered lifetime is controlled by LocalDOMWindow. After // DOMWindowProperty lifetime isn't tied directly to the LocalDOMWindow itself so it is important that it unregister
// the willDestroyGlobalObjectInFrame() notifications, LocalDOMWindow clears out // itself from any LocalDOMWindow it is associated with if that LocalDOMWindow is going away.
// all registrations. Hence no need to unregister. if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
m_associatedDOMWindow = nullptr;
m_frame = nullptr; m_frame = nullptr;
} }
...@@ -59,6 +74,12 @@ void DOMWindowProperty::willDetachGlobalObjectFromFrame() ...@@ -59,6 +74,12 @@ void DOMWindowProperty::willDetachGlobalObjectFromFrame()
{ {
// If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them. // If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them.
ASSERT(m_frame); ASSERT(m_frame);
ASSERT(m_associatedDOMWindow);
} }
} // namespace blink void DOMWindowProperty::trace(Visitor* visitor)
{
visitor->trace(m_associatedDOMWindow);
}
}
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
namespace blink { namespace blink {
class LocalDOMWindow;
class LocalFrame; class LocalFrame;
class DOMWindowProperty : public WillBeGarbageCollectedMixin { class DOMWindowProperty : public WillBeGarbageCollectedMixin {
DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(DOMWindowProperty);
public: public:
explicit DOMWindowProperty(LocalFrame*); explicit DOMWindowProperty(LocalFrame*);
...@@ -42,10 +42,15 @@ public: ...@@ -42,10 +42,15 @@ public:
LocalFrame* frame() const { return m_frame; } LocalFrame* frame() const { return m_frame; }
virtual void trace(Visitor*) { } virtual void trace(Visitor*);
protected: protected:
#if !ENABLE(OILPAN)
virtual ~DOMWindowProperty();
#endif
LocalFrame* m_frame; LocalFrame* m_frame;
RawPtrWillBeMember<LocalDOMWindow> m_associatedDOMWindow;
}; };
} }
......
...@@ -556,14 +556,22 @@ void LocalDOMWindow::willDetachFrameHost() ...@@ -556,14 +556,22 @@ void LocalDOMWindow::willDetachFrameHost()
void LocalDOMWindow::willDestroyDocumentInFrame() void LocalDOMWindow::willDestroyDocumentInFrame()
{ {
for (WillBeHeapHashSet<RawPtrWillBeMember<DOMWindowProperty> >::const_iterator it = m_properties.begin(); it != m_properties.end(); ++it) // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
(*it)->willDestroyGlobalObjectInFrame(); // unregister themselves from the LocalDOMWindow as a result of the call to willDestroyGlobalObjectInFrame.
WillBeHeapVector<RawPtrWillBeMember<DOMWindowProperty> > properties;
copyToVector(m_properties, properties);
for (size_t i = 0; i < properties.size(); ++i)
properties[i]->willDestroyGlobalObjectInFrame();
} }
void LocalDOMWindow::willDetachDocumentFromFrame() void LocalDOMWindow::willDetachDocumentFromFrame()
{ {
for (WillBeHeapHashSet<RawPtrWillBeMember<DOMWindowProperty> >::const_iterator it = m_properties.begin(); it != m_properties.end(); ++it) // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
(*it)->willDetachGlobalObjectFromFrame(); // unregister themselves from the LocalDOMWindow as a result of the call to willDetachGlobalObjectFromFrame.
WillBeHeapVector<RawPtrWillBeMember<DOMWindowProperty> > properties;
copyToVector(m_properties, properties);
for (size_t i = 0; i < properties.size(); ++i)
properties[i]->willDetachGlobalObjectFromFrame();
} }
void LocalDOMWindow::registerProperty(DOMWindowProperty* property) void LocalDOMWindow::registerProperty(DOMWindowProperty* property)
...@@ -571,6 +579,11 @@ void LocalDOMWindow::registerProperty(DOMWindowProperty* property) ...@@ -571,6 +579,11 @@ void LocalDOMWindow::registerProperty(DOMWindowProperty* property)
m_properties.add(property); m_properties.add(property);
} }
void LocalDOMWindow::unregisterProperty(DOMWindowProperty* property)
{
m_properties.remove(property);
}
void LocalDOMWindow::reset() void LocalDOMWindow::reset()
{ {
willDestroyDocumentInFrame(); willDestroyDocumentInFrame();
......
...@@ -112,6 +112,7 @@ public: ...@@ -112,6 +112,7 @@ public:
virtual LocalDOMWindow* toDOMWindow() OVERRIDE; virtual LocalDOMWindow* toDOMWindow() OVERRIDE;
void registerProperty(DOMWindowProperty*); void registerProperty(DOMWindowProperty*);
void unregisterProperty(DOMWindowProperty*);
void reset(); void reset();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment