Title: [93736] branches/chromium/835
- Revision
- 93736
- Author
- cev...@google.com
- Date
- 2011-08-24 14:25:07 -0700 (Wed, 24 Aug 2011)
Log Message
Merge 93521
BUG=89219
Review URL: http://codereview.chromium.org/7727007
Modified Paths
Added Paths
Diff
Copied: branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload-expected.txt (from rev 93521, trunk/LayoutTests/fast/loader/document-destruction-within-unload-expected.txt) (0 => 93736)
--- branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload-expected.txt (rev 0)
+++ branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload-expected.txt 2011-08-24 21:25:07 UTC (rev 93736)
@@ -0,0 +1,2 @@
+
+For the test to pass there should be no crash.
Copied: branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload.html (from rev 93521, trunk/LayoutTests/fast/loader/document-destruction-within-unload.html) (0 => 93736)
--- branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload.html (rev 0)
+++ branches/chromium/835/LayoutTests/fast/loader/document-destruction-within-unload.html 2011-08-24 21:25:07 UTC (rev 93736)
@@ -0,0 +1,17 @@
+<html>
+<body>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function done() {
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+<iframe src=""
+<p>For the test to pass there should be no crash.</p>
+</body>
+</html>
Copied: branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html (from rev 93521, trunk/LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html) (0 => 93736)
--- branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html (rev 0)
+++ branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html 2011-08-24 21:25:07 UTC (rev 93736)
@@ -0,0 +1,18 @@
+<html>
+<body>
+<script>
+function runTest() {
+ var test = document.getElementById('root').contentDocument;
+ test.firstChild.setAttribute('onunload', "parent.clearUs();");
+ location.reload();
+}
+
+function clearUs() {
+ document.write();
+ parent.done();
+}
+</script>
+<object data=""
+<object data="" id="root" _onload_="runTest();"></object>
+</body>
+</html>
Copied: branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload.svg (from rev 93521, trunk/LayoutTests/fast/loader/resources/document-destruction-within-unload.svg) (0 => 93736)
--- branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload.svg (rev 0)
+++ branches/chromium/835/LayoutTests/fast/loader/resources/document-destruction-within-unload.svg 2011-08-24 21:25:07 UTC (rev 93736)
@@ -0,0 +1,2 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+</svg>
Modified: branches/chromium/835/Source/WebCore/loader/FrameLoader.cpp (93735 => 93736)
--- branches/chromium/835/Source/WebCore/loader/FrameLoader.cpp 2011-08-24 21:20:13 UTC (rev 93735)
+++ branches/chromium/835/Source/WebCore/loader/FrameLoader.cpp 2011-08-24 21:25:07 UTC (rev 93736)
@@ -367,7 +367,7 @@
Node* currentFocusedNode = m_frame->document()->focusedNode();
if (currentFocusedNode)
currentFocusedNode->aboutToUnload();
- if (m_frame->domWindow()) {
+ if (m_frame->domWindow() && m_pageDismissalEventBeingDispatched == NoDismissal) {
if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
m_pageDismissalEventBeingDispatched = PageHideDismissal;
m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
@@ -1678,6 +1678,20 @@
m_documentLoader->detachFromFrame();
m_documentLoader = loader;
+
+ // The following abomination is brought to you by the unload event.
+ // The detachChildren() call above may trigger a child frame's unload event,
+ // which could do something obnoxious like call document.write("") on
+ // the main frame, which results in detaching children while detaching children.
+ // This can cause the new m_documentLoader to be detached from its Frame*, but still
+ // be alive. To make matters worse, DocumentLoaders with a null Frame* aren't supposed
+ // to happen when they're still alive (and many places below us on the stack think the
+ // DocumentLoader is still usable). Ergo, we reattach loader to its Frame, and pretend
+ // like nothing ever happened.
+ if (m_documentLoader && !m_documentLoader->frame()) {
+ ASSERT(!m_documentLoader->isLoading());
+ m_documentLoader->setFrame(m_frame);
+ }
}
void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
@@ -2348,12 +2362,14 @@
void FrameLoader::detachChildren()
{
- // FIXME: Is it really necessary to do this in reverse order?
- Frame* previous;
- for (Frame* child = m_frame->tree()->lastChild(); child; child = previous) {
- previous = child->tree()->previousSibling();
- child->loader()->detachFromParent();
- }
+ typedef Vector<RefPtr<Frame> > FrameVector;
+ FrameVector childrenToDetach;
+ childrenToDetach.reserveCapacity(m_frame->tree()->childCount());
+ for (Frame* child = m_frame->tree()->lastChild(); child; child = child->tree()->previousSibling())
+ childrenToDetach.append(child);
+ FrameVector::iterator end = childrenToDetach.end();
+ for (FrameVector::iterator it = childrenToDetach.begin(); it != end; it++)
+ (*it)->loader()->detachFromParent();
}
void FrameLoader::closeAndRemoveChild(Frame* child)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes