Modified: trunk/Source/WebKit2/ChangeLog (181990 => 181991)
--- trunk/Source/WebKit2/ChangeLog 2015-03-26 01:26:56 UTC (rev 181990)
+++ trunk/Source/WebKit2/ChangeLog 2015-03-26 02:36:08 UTC (rev 181991)
@@ -1,3 +1,52 @@
+2015-03-25 Chris Dumez <[email protected]>
+
+ [WK2] WebFrameLoaderClient::dispatchDecidePolicyForResponse() should always call the FramePolicyFunction
+ https://bugs.webkit.org/show_bug.cgi?id=143036
+ <rdar://problem/20252438>
+ <rdar://problem/13811738>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WebFrameLoaderClient::dispatchDecidePolicyForResponse() should always
+ call the FramePolicyFunction. Previously, it would fail to do in 2
+ cases:
+ - m_frame->page() returns null
+ or
+ - webPage->sendSync() returns false
+
+ If the FramePolicyFunction is not called, we will fail to clear the
+ callback in the PolicyChecker and
+ DocumentLoader::continueAfterContentPolicy() will not be called.
+
+ DocumentLoader::continueAfterContentPolicy() is in charge of resetting
+ m_waitingForContentPolicy flag to false. This could therefore explain
+ the following assertion being hit in DocumentLoader::detachFromFrame()
+ (see <rdar://problem/20252438>):
+ RELEASE_ASSERT(!m_waitingForContentPolicy)
+
+ Also, as the PolicyChecker callback is not cleared, it could make it
+ possible for DocumentLoader::continueAfterContentPolicy() to be called
+ *after* the load is finished, when later canceling the PolicyCallback:
+ FrameLoader::stopAllLoaders()
+ -> PolicyChecker::stopCheck()
+ -> PolicyCallback::cancel()
+ -> DocumentLoader::continueAfterContentPolicy(PolicyIgnore)
+
+ Calling continueAfterContentPolicy(PolicyIgnore) after the load is
+ finished would be bad and could explain some of the crashes we've seen
+ in DocumentLoader::continueAfterContentPolicy() ->
+ DocumentLoader:: stopLoadingForPolicyChange() (see
+ <rdar://problem/13811738>).
+
+ This patch also applies the same fix to
+ dispatchDecidePolicyForNewWindowAction() and
+ dispatchDecidePolicyForNavigationAction() as they use the same pattern.
+
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+
2015-03-25 Tim Horton <[email protected]>
Add a preference to prevent "user-scalable=no" from having any effect
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (181990 => 181991)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2015-03-26 01:26:56 UTC (rev 181990)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2015-03-26 02:36:08 UTC (rev 181991)
@@ -659,8 +659,10 @@
void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
{
WebPage* webPage = m_frame->page();
- if (!webPage)
+ if (!webPage) {
+ function(PolicyIgnore);
return;
+ }
if (!request.url().string()) {
function(PolicyUse);
@@ -686,8 +688,10 @@
unsigned syncSendFlags = IPC::InformPlatformProcessWillSuspend;
if (WebPage::synchronousMessagesShouldSpinRunLoop())
syncSendFlags |= IPC::SpinRunLoopWhileWaitingForReply;
- if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), std::chrono::milliseconds::max(), syncSendFlags))
+ if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), std::chrono::milliseconds::max(), syncSendFlags)) {
+ function(PolicyIgnore);
return;
+ }
// We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
if (receivedPolicyAction)
@@ -697,8 +701,10 @@
void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, FramePolicyFunction function)
{
WebPage* webPage = m_frame->page();
- if (!webPage)
+ if (!webPage) {
+ function(PolicyIgnore);
return;
+ }
RefPtr<API::Object> userData;
@@ -727,8 +733,10 @@
void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
{
WebPage* webPage = m_frame->page();
- if (!webPage)
+ if (!webPage) {
+ function(PolicyIgnore);
return;
+ }
// Always ignore requests with empty URLs.
if (request.isEmpty()) {
@@ -788,8 +796,10 @@
documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
// Notify the UIProcess.
- if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID)))
+ if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID))) {
+ function(PolicyIgnore);
return;
+ }
// We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
if (receivedPolicyAction)