Title: [232147] trunk/Source/WebCore
Revision
232147
Author
[email protected]
Date
2018-05-23 22:23:00 -0700 (Wed, 23 May 2018)

Log Message

Avoid keeping FormState alive longer than necessary
https://bugs.webkit.org/show_bug.cgi?id=185877
<rdar://problem/39329219>

Reviewed by Ryosuke Niwa.

A number of crash fixes were done to prevent FormState objects from being
accessed after their relevant Frames had been destroyed. Unfortunately, this
could cause the FormState to persist after the owning Frame had been
destroyed, resulting in nullptr dereferences.

This patch does the following:

1. Uses WeakPtr's for FormState objects passed to completion handlers, rather
   than RefPtr, since those completion handlers might fire as part of the
   clean-up process during Frame destruction. This allows us to use the FormState
   if they are still valid, but gracefully handle cases where a form submission
   is cancelled in-flight.
2. Moves FormState object as they pass through the loader.
3. Removes some extraneous WTFMove() calls being made on bare FormState pointers.
4. Changes FormSubmission to hold a RefPtr so we can move the FormState to the
   loader in the code path that uses it (the FormSubmission is always destroyed
   shortly afterwards).
5. Changes the trap from Bug 183704 so that it only fires if the FormState object
   is being retained more than once.

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::willSendRequest): Update for new CompletionHandler
signature.
* loader/FormState.cpp:
(WebCore::FormState::willDetachPage): Revise trap to check for retain counts
above one.
* loader/FormState.h:
(WebCore::FormState::weakPtrFactory const): Added.
* loader/FormSubmission.h:
(WebCore::FormSubmission::state const): Revised for change to RefPtr.
(WebCore::FormSubmission::takeState): Added.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected): Update for new CompletionHandler signature.
(WebCore::FrameLoader::loadURLIntoChildFrame): Ditto.
(WebCore::FrameLoader::loadFrameRequest): Ditto.
(WebCore::FrameLoader::loadURL): Ditto.
(WebCore::FrameLoader::load): Ditto.
(WebCore::FrameLoader::loadWithNavigationAction): Ditto.
(WebCore::FrameLoader::loadWithDocumentLoader): Ditto.
(WebCore::FrameLoader::reloadWithOverrideEncoding): Ditto.
(WebCore::FrameLoader::reload): Ditto.
(WebCore::FrameLoader::loadPostRequest): Ditto.
(WebCore::FrameLoader::loadDifferentDocumentItem): Ditto.
* loader/FrameLoader.h:
* loader/NavigationScheduler.cpp:
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):Revise to use WeakPtr for
FormState passed to the completion handler. Remove some extraneous WTFMove()
calls on bare pointers.
(WebCore::PolicyChecker::checkNewWindowPolicy): Ditto.
* loader/PolicyChecker.h:
* page/ContextMenuController.cpp:
(WebCore::openNewWindow): Revise for new signatures.
(WebCore::ContextMenuController::contextMenuItemSelected): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (232146 => 232147)


--- trunk/Source/WebCore/ChangeLog	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/ChangeLog	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,3 +1,66 @@
+2018-05-23  Brent Fulgham  <[email protected]>
+
+        Avoid keeping FormState alive longer than necessary
+        https://bugs.webkit.org/show_bug.cgi?id=185877
+        <rdar://problem/39329219>
+
+        Reviewed by Ryosuke Niwa.
+
+        A number of crash fixes were done to prevent FormState objects from being
+        accessed after their relevant Frames had been destroyed. Unfortunately, this
+        could cause the FormState to persist after the owning Frame had been
+        destroyed, resulting in nullptr dereferences.
+
+        This patch does the following:
+
+        1. Uses WeakPtr's for FormState objects passed to completion handlers, rather
+           than RefPtr, since those completion handlers might fire as part of the
+           clean-up process during Frame destruction. This allows us to use the FormState
+           if they are still valid, but gracefully handle cases where a form submission
+           is cancelled in-flight.
+        2. Moves FormState object as they pass through the loader.
+        3. Removes some extraneous WTFMove() calls being made on bare FormState pointers.
+        4. Changes FormSubmission to hold a RefPtr so we can move the FormState to the
+           loader in the code path that uses it (the FormSubmission is always destroyed
+           shortly afterwards).
+        5. Changes the trap from Bug 183704 so that it only fires if the FormState object
+           is being retained more than once.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::willSendRequest): Update for new CompletionHandler
+        signature.
+        * loader/FormState.cpp:
+        (WebCore::FormState::willDetachPage): Revise trap to check for retain counts
+        above one.
+        * loader/FormState.h:
+        (WebCore::FormState::weakPtrFactory const): Added.
+        * loader/FormSubmission.h:
+        (WebCore::FormSubmission::state const): Revised for change to RefPtr.
+        (WebCore::FormSubmission::takeState): Added.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::urlSelected): Update for new CompletionHandler signature.
+        (WebCore::FrameLoader::loadURLIntoChildFrame): Ditto.
+        (WebCore::FrameLoader::loadFrameRequest): Ditto.
+        (WebCore::FrameLoader::loadURL): Ditto.
+        (WebCore::FrameLoader::load): Ditto.
+        (WebCore::FrameLoader::loadWithNavigationAction): Ditto.
+        (WebCore::FrameLoader::loadWithDocumentLoader): Ditto.
+        (WebCore::FrameLoader::reloadWithOverrideEncoding): Ditto.
+        (WebCore::FrameLoader::reload): Ditto.
+        (WebCore::FrameLoader::loadPostRequest): Ditto.
+        (WebCore::FrameLoader::loadDifferentDocumentItem): Ditto.
+        * loader/FrameLoader.h:
+        * loader/NavigationScheduler.cpp:
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):Revise to use WeakPtr for
+        FormState passed to the completion handler. Remove some extraneous WTFMove()
+        calls on bare pointers.
+        (WebCore::PolicyChecker::checkNewWindowPolicy): Ditto.
+        * loader/PolicyChecker.h:
+        * page/ContextMenuController.cpp:
+        (WebCore::openNewWindow): Revise for new signatures.
+        (WebCore::ContextMenuController::contextMenuItemSelected): Ditto.
+
 2018-05-23  Keith Miller  <[email protected]>
 
         Expose $vm if window.internals is exposed

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (232146 => 232147)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -640,7 +640,7 @@
     if (!didReceiveRedirectResponse && shouldContinue != ShouldContinue::ForSuspension)
         return completionHandler(WTFMove(newRequest));
 
-    auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, FormState*, ShouldContinue shouldContinue) mutable {
+    auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) mutable {
         m_waitingForNavigationPolicy = false;
         switch (shouldContinue) {
         case ShouldContinue::ForSuspension:

Modified: trunk/Source/WebCore/loader/FormState.cpp (232146 => 232147)


--- trunk/Source/WebCore/loader/FormState.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/FormState.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,7 +52,7 @@
 void FormState::willDetachPage()
 {
     // Beartrap for <rdar://problem/37579354>
-    RELEASE_ASSERT_NOT_REACHED();
+    RELEASE_ASSERT(hasOneRef());
 }
 
 }

Modified: trunk/Source/WebCore/loader/FormState.h (232146 => 232147)


--- trunk/Source/WebCore/loader/FormState.h	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/FormState.h	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #pragma once
 
 #include "FrameDestructionObserver.h"
+#include <wtf/WeakPtr.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -49,6 +50,8 @@
     Document& sourceDocument() const { return m_sourceDocument; }
     FormSubmissionTrigger formSubmissionTrigger() const { return m_formSubmissionTrigger; }
 
+    auto& weakPtrFactory() const { return m_weakFactory; }
+
 private:
     FormState(HTMLFormElement&, StringPairVector&& textFieldValues, Document&, FormSubmissionTrigger);
     void willDetachPage() override;
@@ -57,6 +60,7 @@
     StringPairVector m_textFieldValues;
     Ref<Document> m_sourceDocument;
     FormSubmissionTrigger m_formSubmissionTrigger;
+    WeakPtrFactory<FormState> m_weakFactory;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/loader/FormSubmission.h (232146 => 232147)


--- trunk/Source/WebCore/loader/FormSubmission.h	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/FormSubmission.h	2018-05-24 05:23:00 UTC (rev 232147)
@@ -83,7 +83,8 @@
     const URL& action() const { return m_action; }
     const String& target() const { return m_target; }
     const String& contentType() const { return m_contentType; }
-    FormState& state() const { return m_formState; }
+    FormState& state() const { return *m_formState; }
+    Ref<FormState> takeState() { return m_formState.releaseNonNull(); }
     FormData& data() const { return m_formData; }
     const String boundary() const { return m_boundary; }
     LockHistory lockHistory() const { return m_lockHistory; }
@@ -103,7 +104,7 @@
     URL m_action;
     String m_target;
     String m_contentType;
-    Ref<FormState> m_formState;
+    RefPtr<FormState> m_formState;
     Ref<FormData> m_formData;
     String m_boundary;
     LockHistory m_lockHistory;

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (232146 => 232147)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2008 Alp Toker <[email protected]>
@@ -392,7 +392,7 @@
     addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
     m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(frameRequest.resourceRequest(), ContentSecurityPolicy::InsecureRequestType::Navigation);
 
-    loadFrameRequest(WTFMove(frameRequest), triggeringEvent, nullptr);
+    loadFrameRequest(WTFMove(frameRequest), triggeringEvent, { });
 }
 
 void FrameLoader::submitForm(Ref<FormSubmission>&& submission)
@@ -957,7 +957,7 @@
     auto initiatedByMainFrame = lexicalFrame && lexicalFrame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
 
     FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow, initiatedByMainFrame };
-    childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, nullptr, [] { });
+    childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, { }, [] { });
 }
 
 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
@@ -1199,7 +1199,7 @@
     detachChildren();
 }
 
-void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, FormState* formState)
+void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, RefPtr<FormState>&& formState)
 {
     // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
     auto protectFrame = makeRef(m_frame);
@@ -1228,7 +1228,7 @@
     else
         loadType = FrameLoadType::Standard;
 
-    auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeRefPtr(formState), frameName = request.frameName()] {
+    auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeWeakPtr(formState.get()), frameName = request.frameName()] {
         // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
         // load if frame names have changed.
         Frame* sourceFrame = formState ? formState->sourceDocument().frame() : &m_frame;
@@ -1242,9 +1242,9 @@
     };
 
     if (request.resourceRequest().httpMethod() == "POST")
-        loadPostRequest(WTFMove(request), referrer, loadType, event, formState, WTFMove(completionHandler));
+        loadPostRequest(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(completionHandler));
     else
-        loadURL(WTFMove(request), referrer, loadType, event, formState, WTFMove(completionHandler));
+        loadURL(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(completionHandler));
 }
 
 static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
@@ -1286,7 +1286,7 @@
     return m_pageDismissalEventBeingDispatched == PageDismissalType::None;
 }
 
-void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, FormState* formState, CompletionHandler<void()>&& completionHandler)
+void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, RefPtr<FormState>&& formState, CompletionHandler<void()>&& completionHandler)
 {
     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
     if (m_inStopAllLoaders)
@@ -1320,7 +1320,7 @@
     Frame* targetFrame = isFormSubmission ? nullptr : findFrameForNavigation(frameName);
     if (targetFrame && targetFrame != &m_frame) {
         frameLoadRequest.setFrameName("_self");
-        targetFrame->loader().loadURL(WTFMove(frameLoadRequest), referrer, newLoadType, event, formState, completionHandlerCaller.release());
+        targetFrame->loader().loadURL(WTFMove(frameLoadRequest), referrer, newLoadType, event, WTFMove(formState), completionHandlerCaller.release());
         return;
     }
 
@@ -1338,8 +1338,8 @@
 
     if (!targetFrame && !frameName.isEmpty()) {
         action = "" frameLoadRequest));
-        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
+        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
+            continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
             completionHandler();
         });
         return;
@@ -1358,7 +1358,7 @@
         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
         policyChecker().stopCheck();
         policyChecker().setLoadType(newLoadType);
-        policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) {
+        policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) {
             continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes);
         }, PolicyDecisionMode::Synchronous);
         return;
@@ -1372,7 +1372,7 @@
     if (isSystemPreview)
         request.setSystemPreviewRect(frameLoadRequest.systemPreviewRect());
 #endif
-    loadWithNavigationAction(request, action, lockHistory, newLoadType, formState, allowNavigationToInvalidURL, [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] {
+    loadWithNavigationAction(request, action, lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] {
         if (isRedirect) {
             m_quickRedirectComing = false;
             if (m_provisionalDocumentLoader)
@@ -1419,8 +1419,8 @@
 
     if (request.shouldCheckNewWindowPolicy()) {
         NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() };
-        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), nullptr, request.frameName(), [this] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
+        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), { }, request.frameName(), [this] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
+            continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         });
 
         return;
@@ -1437,7 +1437,7 @@
     load(loader.ptr());
 }
 
-void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, FormState* formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, CompletionHandler<void()>&& completionHandler)
+void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, CompletionHandler<void()>&& completionHandler)
 {
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
@@ -1449,7 +1449,7 @@
     if (m_documentLoader)
         loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
 
-    loadWithDocumentLoader(loader.ptr(), type, formState, allowNavigationToInvalidURL, NavigationPolicyCheck::Require, WTFMove(completionHandler));
+    loadWithDocumentLoader(loader.ptr(), type, WTFMove(formState), allowNavigationToInvalidURL, NavigationPolicyCheck::Require, WTFMove(completionHandler));
 }
 
 void FrameLoader::load(DocumentLoader* newDocumentLoader)
@@ -1488,10 +1488,10 @@
         type = FrameLoadType::Reload;
     }
 
-    loadWithDocumentLoader(newDocumentLoader, type, 0, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
+    loadWithDocumentLoader(newDocumentLoader, type, { }, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
 }
 
-void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, FormState* formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NavigationPolicyCheck, CompletionHandler<void()>&& completionHandler)
+void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NavigationPolicyCheck, CompletionHandler<void()>&& completionHandler)
 {
     // Retain because dispatchBeforeLoadEvent may release the last reference to it.
     Ref<Frame> protect(m_frame);
@@ -1533,7 +1533,7 @@
         oldDocumentLoader->setTriggeringAction(action);
         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
         policyChecker().stopCheck();
-        policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) {
+        policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) {
             continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes);
         }, PolicyDecisionMode::Synchronous);
         return;
@@ -1555,7 +1555,7 @@
         // a new URL, the parent frame shouldn't learn the URL.
         if (!m_stateMachine.committedFirstRealDocumentLoad()
             && !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
-            continueLoadAfterNavigationPolicy(loader->request(), formState, ShouldContinue::No, allowNavigationToInvalidURL);
+            continueLoadAfterNavigationPolicy(loader->request(), formState.get(), ShouldContinue::No, allowNavigationToInvalidURL);
             return;
         }
     }
@@ -1563,12 +1563,12 @@
     m_frame.navigationScheduler().cancel(true);
 
     if (!m_currentLoadShouldCheckNavigationPolicy) {
-        continueLoadAfterNavigationPolicy(loader->request(), formState, ShouldContinue::Yes, allowNavigationToInvalidURL);
+        continueLoadAfterNavigationPolicy(loader->request(), formState.get(), ShouldContinue::Yes, allowNavigationToInvalidURL);
         return;
     }
 
-    policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, formState, [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState* formState, ShouldContinue shouldContinue) {
-        continueLoadAfterNavigationPolicy(request, formState, shouldContinue, allowNavigationToInvalidURL);
+    policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, WTFMove(formState), [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, ShouldContinue shouldContinue) {
+        continueLoadAfterNavigationPolicy(request, formState.get(), shouldContinue, allowNavigationToInvalidURL);
         completionHandler();
     });
 }
@@ -1676,7 +1676,7 @@
 
     loader->setOverrideEncoding(encoding);
 
-    loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, 0, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
+    loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, { }, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
 }
 
 void FrameLoader::reload(OptionSet<ReloadOption> options)
@@ -1723,7 +1723,7 @@
         return FrameLoadType::Reload;
     };
     
-    loadWithDocumentLoader(loader.ptr(), frameLoadTypeForReloadOptions(options), 0, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
+    loadWithDocumentLoader(loader.ptr(), frameLoadTypeForReloadOptions(options), { }, AllowNavigationToInvalidURL::Yes, NavigationPolicyCheck::Require, [] { });
 }
 
 void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy)
@@ -2832,7 +2832,7 @@
     request.setHTTPHeaderField(HTTPHeaderName::UpgradeInsecureRequests, ASCIILiteral("1"));
 }
 
-void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& referrer, FrameLoadType loadType, Event* event, FormState* formState, CompletionHandler<void()>&& completionHandler)
+void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& referrer, FrameLoadType loadType, Event* event, RefPtr<FormState>&& formState, CompletionHandler<void()>&& completionHandler)
 {
     String frameName = request.frameName();
     LockHistory lockHistory = request.lockHistory();
@@ -2861,13 +2861,13 @@
 
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
-        if (Frame* targetFrame = formState ? 0 : findFrameForNavigation(frameName)) {
+        if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
             targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, WTFMove(completionHandler));
             return;
         }
 
-        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
+        policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
+            continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
             completionHandler();
         });
         return;
@@ -3533,7 +3533,7 @@
         documentLoader->setTriggeringAction(WTFMove(action));
 
         documentLoader->setLastCheckedRequest(ResourceRequest());
-        loadWithDocumentLoader(documentLoader, loadType, 0, AllowNavigationToInvalidURL::Yes, navigationPolicyCheck, [] { });
+        loadWithDocumentLoader(documentLoader, loadType, { }, AllowNavigationToInvalidURL::Yes, navigationPolicyCheck, [] { });
         return;
     }
 
@@ -3621,7 +3621,7 @@
 
     action.setTargetBackForwardItem(item);
 
-    loadWithNavigationAction(request, action, LockHistory::No, loadType, 0, AllowNavigationToInvalidURL::Yes, [] { });
+    loadWithNavigationAction(request, action, LockHistory::No, loadType, { }, AllowNavigationToInvalidURL::Yes, [] { });
 }
 
 // Loads content into this frame, as specified by history item

Modified: trunk/Source/WebCore/loader/FrameLoader.h (232146 => 232147)


--- trunk/Source/WebCore/loader/FrameLoader.h	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2018-05-24 05:23:00 UTC (rev 232147)
@@ -111,7 +111,7 @@
 
     // FIXME: These are all functions which start loads. We have too many.
     WEBCORE_EXPORT void loadURLIntoChildFrame(const URL&, const String& referer, Frame*);
-    WEBCORE_EXPORT void loadFrameRequest(FrameLoadRequest&&, Event*, FormState*); // Called by submitForm, calls loadPostRequest and loadURL.
+    WEBCORE_EXPORT void loadFrameRequest(FrameLoadRequest&&, Event*, RefPtr<FormState>&&); // Called by submitForm, calls loadPostRequest and loadURL.
 
     WEBCORE_EXPORT void load(FrameLoadRequest&&);
 
@@ -364,13 +364,13 @@
 
     void urlSelected(FrameLoadRequest&&, Event*);
 
-    void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, FormState*, AllowNavigationToInvalidURL, NavigationPolicyCheck, CompletionHandler<void()>&&); // Calls continueLoadAfterNavigationPolicy
+    void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, NavigationPolicyCheck, CompletionHandler<void()>&&); // Calls continueLoadAfterNavigationPolicy
     void load(DocumentLoader*); // Calls loadWithDocumentLoader
 
-    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, FormState*, AllowNavigationToInvalidURL, CompletionHandler<void()>&&); // Calls loadWithDocumentLoader
+    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, CompletionHandler<void()>&&); // Calls loadWithDocumentLoader
 
-    void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*, CompletionHandler<void()>&&);
-    void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*, CompletionHandler<void()>&&);
+    void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
+    void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
 
     bool shouldReload(const URL& currentURL, const URL& destinationURL);
 

Modified: trunk/Source/WebCore/loader/NavigationScheduler.cpp (232146 => 232147)


--- trunk/Source/WebCore/loader/NavigationScheduler.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/NavigationScheduler.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -274,7 +274,7 @@
             return;
         FrameLoadRequest frameLoadRequest { requestingDocument, requestingDocument.securityOrigin(), { }, { }, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), initiatedByMainFrame() };
         m_submission->populateFrameLoadRequest(frameLoadRequest);
-        frame.loader().loadFrameRequest(WTFMove(frameLoadRequest), m_submission->event(), &m_submission->state());
+        frame.loader().loadFrameRequest(WTFMove(frameLoadRequest), m_submission->event(), m_submission->takeState());
     }
 
     void didStartTimer(Frame& frame, Timer& timer) override

Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (232146 => 232147)


--- trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  *
@@ -81,7 +81,7 @@
 
 void PolicyChecker::checkNavigationPolicy(ResourceRequest&& newRequest, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&& function)
 {
-    checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), nullptr, WTFMove(function));
+    checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function));
 }
 
 CompletionHandlerCallingScope PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request) const
@@ -98,7 +98,7 @@
     });
 }
 
-void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, DocumentLoader* loader, FormState* formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode)
+void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, DocumentLoader* loader, RefPtr<FormState>&& formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode)
 {
     NavigationAction action = ""
     if (action.isEmpty()) {
@@ -109,7 +109,7 @@
     // Don't ask more than once for the same request or if we are loading an empty URL.
     // This avoids confusion on the part of the client.
     if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
-        function(ResourceRequest(request), nullptr, ShouldContinue::Yes);
+        function(ResourceRequest(request), { }, ShouldContinue::Yes);
         loader->setLastCheckedRequest(WTFMove(request));
         return;
     }
@@ -124,7 +124,7 @@
 #endif
         if (isBackForwardLoadType(m_loadType))
             m_loadType = FrameLoadType::Reload;
-        function(WTFMove(request), nullptr, shouldContinue ? ShouldContinue::Yes : ShouldContinue::No);
+        function(WTFMove(request), { }, shouldContinue ? ShouldContinue::Yes : ShouldContinue::No);
         return;
     }
 
@@ -134,7 +134,7 @@
             // reveal that the frame was blocked. This way, it looks like any other cross-origin page load.
             m_frame.ownerElement()->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
         }
-        function(WTFMove(request), nullptr, ShouldContinue::No);
+        function(WTFMove(request), { }, ShouldContinue::No);
         return;
     }
 
@@ -147,7 +147,7 @@
 #if USE(QUICK_LOOK)
     // Always allow QuickLook-generated URLs based on the protocol scheme.
     if (!request.isNull() && isQuickLookPreviewURL(request.url()))
-        return function(WTFMove(request), formState, ShouldContinue::Yes);
+        return function(WTFMove(request), makeWeakPtr(formState.get()), ShouldContinue::Yes);
 #endif
 
 #if ENABLE(CONTENT_FILTERING)
@@ -168,7 +168,7 @@
 
     m_delegateIsDecidingNavigationPolicy = true;
     String suggestedFilename = action.downloadAttribute().isEmpty() ? nullAtom() : action.downloadAttribute();
-    m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = makeRefPtr(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {
+    m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState.get(), policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = WTFMove(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {
         m_delegateIsDecidingNavigationPolicy = false;
 
         switch (policyAction) {
@@ -183,15 +183,15 @@
         case PolicyAction::Use:
             if (!m_frame.loader().client().canHandleRequest(request)) {
                 handleUnimplementablePolicy(m_frame.loader().client().cannotShowURLError(request));
-                return function({ }, nullptr, ShouldContinue::No);
+                return function({ }, { }, ShouldContinue::No);
             }
-            return function(WTFMove(request), formState.get(), ShouldContinue::Yes);
+            return function(WTFMove(request), makeWeakPtr(formState.get()), ShouldContinue::Yes);
         }
         ASSERT_NOT_REACHED();
     });
 }
 
-void PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigationAction, ResourceRequest&& request, FormState* formState, const String& frameName, NewWindowPolicyDecisionFunction&& function)
+void PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigationAction, ResourceRequest&& request, RefPtr<FormState>&& formState, const String& frameName, NewWindowPolicyDecisionFunction&& function)
 {
     if (m_frame.document() && m_frame.document()->isSandboxed(SandboxPopups))
         return function({ }, nullptr, { }, { }, ShouldContinue::No);
@@ -201,7 +201,7 @@
 
     auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request);
 
-    m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState, frameName, [frame = makeRef(m_frame), request, formState = makeRefPtr(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {
+    m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState.get(), frameName, [frame = makeRef(m_frame), request, formState = WTFMove(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {
         switch (policyAction) {
         case PolicyAction::Download:
             frame->loader().client().startDownload(request);
@@ -213,7 +213,7 @@
             // It is invalid to get a "Suspend" policy for new windows, as the old document is not going away.
             RELEASE_ASSERT_NOT_REACHED();
         case PolicyAction::Use:
-            function(request, formState.get(), frameName, navigationAction, ShouldContinue::Yes);
+            function(request, makeWeakPtr(formState.get()), frameName, navigationAction, ShouldContinue::Yes);
             return;
         }
         ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/loader/PolicyChecker.h (232146 => 232147)


--- trunk/Source/WebCore/loader/PolicyChecker.h	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/loader/PolicyChecker.h	2018-05-24 05:23:00 UTC (rev 232147)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
 
 #include "FrameLoaderTypes.h"
 #include "ResourceRequest.h"
+#include <wtf/WeakPtr.h>
 #include <wtf/text/WTFString.h>
 
 #if ENABLE(CONTENT_FILTERING)
@@ -59,8 +60,8 @@
 
 enum class PolicyDecisionMode { Synchronous, Asynchronous };
 
-using NewWindowPolicyDecisionFunction = CompletionHandler<void(const ResourceRequest&, FormState*, const String& frameName, const NavigationAction&, ShouldContinue)>;
-using NavigationPolicyDecisionFunction = CompletionHandler<void(ResourceRequest&&, FormState*, ShouldContinue)>;
+using NewWindowPolicyDecisionFunction = CompletionHandler<void(const ResourceRequest&, WeakPtr<FormState>&&, const String& frameName, const NavigationAction&, ShouldContinue)>;
+using NavigationPolicyDecisionFunction = CompletionHandler<void(ResourceRequest&&, WeakPtr<FormState>&&, ShouldContinue)>;
 
 class PolicyChecker {
     WTF_MAKE_NONCOPYABLE(PolicyChecker);
@@ -68,9 +69,9 @@
 public:
     explicit PolicyChecker(Frame&);
 
-    void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, DocumentLoader*, FormState*, NavigationPolicyDecisionFunction&&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous);
+    void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, DocumentLoader*, RefPtr<FormState>&&, NavigationPolicyDecisionFunction&&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous);
     void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&&);
-    void checkNewWindowPolicy(NavigationAction&&, ResourceRequest&&, FormState*, const String& frameName, NewWindowPolicyDecisionFunction&&);
+    void checkNewWindowPolicy(NavigationAction&&, ResourceRequest&&, RefPtr<FormState>&&, const String& frameName, NewWindowPolicyDecisionFunction&&);
 
     void stopCheck();
 

Modified: trunk/Source/WebCore/page/ContextMenuController.cpp (232146 => 232147)


--- trunk/Source/WebCore/page/ContextMenuController.cpp	2018-05-24 04:45:15 UTC (rev 232146)
+++ trunk/Source/WebCore/page/ContextMenuController.cpp	2018-05-24 05:23:00 UTC (rev 232147)
@@ -196,7 +196,7 @@
     if (!newPage)
         return;
     newPage->chrome().show();
-    newPage->mainFrame().loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr, nullptr);
+    newPage->mainFrame().loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr, { });
 }
 
 #if PLATFORM(GTK)
@@ -397,7 +397,7 @@
         if (Frame* targetFrame = m_context.hitTestResult().targetFrame()) {
             ResourceRequest resourceRequest { m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer() };
             FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), resourceRequest, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
-            targetFrame->loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr, nullptr);
+            targetFrame->loader().loadFrameRequest(WTFMove(frameLoadRequest), nullptr,  { });
         } else
             openNewWindow(m_context.hitTestResult().absoluteLinkURL(), *frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
         break;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to