Diff
Modified: branches/safari-603-branch/LayoutTests/ChangeLog (214520 => 214521)
--- branches/safari-603-branch/LayoutTests/ChangeLog 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/LayoutTests/ChangeLog 2017-03-29 03:28:26 UTC (rev 214521)
@@ -1,5 +1,23 @@
2017-03-28 Jason Marcell <jmarc...@apple.com>
+ Merge r214365. rdar://problem/30922115
+
+ 2017-03-24 Daniel Bates <daba...@apple.com>
+
+ Prevent new navigations during document unload
+ https://bugs.webkit.org/show_bug.cgi?id=169934
+ <rdar://problem/31247584>
+
+ Reviewed by Chris Dumez.
+
+ Add a test to ensure that we do not cause an assertion fail when calling setTimeout
+ after starting a navigation from an onunload event handler.
+
+ * fast/frames/frame-unload-navigate-and-setTimeout-assert-fail-expected.txt: Added.
+ * fast/frames/frame-unload-navigate-and-setTimeout-assert-fail.html: Added.
+
+2017-03-28 Jason Marcell <jmarc...@apple.com>
+
Merge r214194. rdar://problem/31101594
2017-03-20 Daniel Bates <daba...@apple.com>
Added: branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail-expected.txt (0 => 214521)
--- branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail-expected.txt (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail-expected.txt 2017-03-29 03:28:26 UTC (rev 214521)
@@ -0,0 +1 @@
+PASS did not crash.
Added: branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail.html (0 => 214521)
--- branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail.html (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/frames/frame-unload-navigate-and-setTimeout-assert-fail.html 2017-03-29 03:28:26 UTC (rev 214521)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+ testRunner.waitUntilDone();
+}
+</script>
+<iframe id="iframe"></iframe>
+<script>
+var frame = document.getElementById("iframe");
+frame.contentWindow._onunload_ = () => {
+ var link = document.createElement('a');
+ link.href = ""
+ link.click();
+
+ window.setTimeout(() => {
+ // Do nothing.
+ }, 0);
+};
+window.location = '_javascript_:"PASS did not crash.<script>window.testRunner && window.testRunner.notifyDone();</' + 'script>"';
+</script>
+</body>
+</html>
Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (214520 => 214521)
--- branches/safari-603-branch/Source/WebCore/ChangeLog 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog 2017-03-29 03:28:26 UTC (rev 214521)
@@ -1,5 +1,46 @@
2017-03-28 Jason Marcell <jmarc...@apple.com>
+ Merge r214365. rdar://problem/30922115
+
+ 2017-03-24 Daniel Bates <daba...@apple.com>
+
+ Prevent new navigations during document unload
+ https://bugs.webkit.org/show_bug.cgi?id=169934
+ <rdar://problem/31247584>
+
+ Reviewed by Chris Dumez.
+
+ Similar to our policy of preventing new navigations from onbeforeunload handlers
+ we should prevent new navigations that are initiated during the document unload
+ process.
+
+ The significant part of this change is the instantiation of the RAII object NavigationDisabler
+ in Document::prepareForDestruction(). The rest of this change just renames class
+ NavigationDisablerForBeforeUnload to NavigationDisabler now that this RAII class is
+ used to prevent navigation from both onbeforeunload event handlers and when unloading
+ a document.
+
+ Test: fast/frames/frame-unload-navigate-and-setTimeout-assert-fail.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::prepareForDestruction): Disable new navigations when disconnecting
+ subframes. Also assert that the document is not in the page cache before we fall off
+ the end of the function.
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::isNavigationAllowed): Update for renaming below.
+ (WebCore::FrameLoader::shouldClose): Ditto.
+ * loader/NavigationScheduler.cpp:
+ (WebCore::NavigationScheduler::shouldScheduleNavigation): Ditto.
+ * loader/NavigationScheduler.h:
+ (WebCore::NavigationDisabler::NavigationDisabler): Renamed class; formerly named NavigationDisablerForBeforeUnload.
+ (WebCore::NavigationDisabler::~NavigationDisabler): Ditto.
+ (WebCore::NavigationDisabler::isNavigationAllowed): Ditto.
+ (WebCore::NavigationDisablerForBeforeUnload::NavigationDisablerForBeforeUnload): Deleted.
+ (WebCore::NavigationDisablerForBeforeUnload::~NavigationDisablerForBeforeUnload): Deleted.
+ (WebCore::NavigationDisablerForBeforeUnload::isNavigationAllowed): Deleted.
+
+2017-03-28 Jason Marcell <jmarc...@apple.com>
+
Merge r214194. rdar://problem/31101594
2017-03-20 Daniel Bates <daba...@apple.com>
Modified: branches/safari-603-branch/Source/WebCore/dom/Document.cpp (214520 => 214521)
--- branches/safari-603-branch/Source/WebCore/dom/Document.cpp 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/Source/WebCore/dom/Document.cpp 2017-03-29 03:28:26 UTC (rev 214521)
@@ -2296,8 +2296,12 @@
cache->clearTextMarkerNodesInUse(this);
}
#endif
-
- disconnectDescendantFrames();
+
+ {
+ NavigationDisabler navigationDisabler;
+ disconnectDescendantFrames();
+ }
+
if (m_domWindow && m_frame)
m_domWindow->willDetachDocumentFromFrame();
@@ -2351,6 +2355,11 @@
disconnectFromFrame();
m_hasPreparedForDestruction = true;
+
+ // Note that m_pageCacheState can be Document::AboutToEnterPageCache if our frame
+ // was removed in an onpagehide event handler fired when the top-level frame is
+ // about to enter the page cache.
+ ASSERT_WITH_SECURITY_IMPLICATION(m_pageCacheState != Document::InPageCache);
}
void Document::removeAllEventListeners()
Modified: branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp (214520 => 214521)
--- branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp 2017-03-29 03:28:26 UTC (rev 214521)
@@ -1195,7 +1195,7 @@
bool FrameLoader::isNavigationAllowed() const
{
- return m_pageDismissalEventBeingDispatched == PageDismissalType::None && NavigationDisablerForBeforeUnload::isNavigationAllowed();
+ return m_pageDismissalEventBeingDispatched == PageDismissalType::None && NavigationDisabler::isNavigationAllowed();
}
void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, PassRefPtr<FormState> prpFormState)
@@ -2949,7 +2949,7 @@
bool shouldClose = false;
{
- NavigationDisablerForBeforeUnload navigationDisabler;
+ NavigationDisabler navigationDisabler;
size_t i;
for (i = 0; i < targetFrames.size(); i++) {
Modified: branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.cpp (214520 => 214521)
--- branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.cpp 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.cpp 2017-03-29 03:28:26 UTC (rev 214521)
@@ -54,7 +54,7 @@
namespace WebCore {
-unsigned NavigationDisablerForBeforeUnload::s_navigationDisableCount = 0;
+unsigned NavigationDisabler::s_navigationDisableCount = 0;
class ScheduledNavigation {
WTF_MAKE_NONCOPYABLE(ScheduledNavigation); WTF_MAKE_FAST_ALLOCATED;
@@ -361,7 +361,7 @@
return false;
if (protocolIsJavaScript(url))
return true;
- return NavigationDisablerForBeforeUnload::isNavigationAllowed();
+ return NavigationDisabler::isNavigationAllowed();
}
void NavigationScheduler::scheduleRedirect(Document* initiatingDocument, double delay, const URL& url)
Modified: branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.h (214520 => 214521)
--- branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.h 2017-03-29 03:28:22 UTC (rev 214520)
+++ branches/safari-603-branch/Source/WebCore/loader/NavigationScheduler.h 2017-03-29 03:28:26 UTC (rev 214521)
@@ -43,13 +43,13 @@
class SecurityOrigin;
class URL;
-class NavigationDisablerForBeforeUnload {
+class NavigationDisabler {
public:
- NavigationDisablerForBeforeUnload()
+ NavigationDisabler()
{
s_navigationDisableCount++;
}
- ~NavigationDisablerForBeforeUnload()
+ ~NavigationDisabler()
{
ASSERT(s_navigationDisableCount);
s_navigationDisableCount--;