Title: [293072] branches/safari-613-branch
Revision
293072
Author
[email protected]
Date
2022-04-19 22:38:27 -0700 (Tue, 19 Apr 2022)

Log Message

Cherry-pick r291606. rdar://problem/91446317

    Website policies are not respected when doing COOP based process swap
    https://bugs.webkit.org/show_bug.cgi?id=238036
    <rdar://89616625>

    Reviewed by Chris Dumez.

    Source/WebKit:

    In case of normal process swap, we make use of website policies so everything is fine.
    For COOP based process swap, this happens later on, at a point where we lost website policies.
    To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
    It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
    We then set the website policies in the navigation object just before continuing the load in the same process,
    as process swap may happen later when inspecting the response.
    Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
    Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.

    Covered by API test.

    * UIProcess/API/APINavigation.h:
    (API::Navigation::setWebsitePoliciesForProcessSwap):
    (API::Navigation::takeWebsitePoliciesForProcessSwap):
    * UIProcess/WebPageProxy.cpp:
    (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
    (WebKit::WebPageProxy::receivedPolicyDecision):
    (WebKit::WebPageProxy::continueNavigationInNewProcess):
    (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
    * UIProcess/WebPageProxy.h:

    Tools:

    * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291606 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-613-branch/Source/WebKit/ChangeLog (293071 => 293072)


--- branches/safari-613-branch/Source/WebKit/ChangeLog	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Source/WebKit/ChangeLog	2022-04-20 05:38:27 UTC (rev 293072)
@@ -1,5 +1,73 @@
 2022-04-19  Alan Coon  <[email protected]>
 
+        Cherry-pick r291606. rdar://problem/91446317
+
+    Website policies are not respected when doing COOP based process swap
+    https://bugs.webkit.org/show_bug.cgi?id=238036
+    <rdar://89616625>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebKit:
+    
+    In case of normal process swap, we make use of website policies so everything is fine.
+    For COOP based process swap, this happens later on, at a point where we lost website policies.
+    To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
+    It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
+    We then set the website policies in the navigation object just before continuing the load in the same process,
+    as process swap may happen later when inspecting the response.
+    Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
+    Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.
+    
+    Covered by API test.
+    
+    * UIProcess/API/APINavigation.h:
+    (API::Navigation::setWebsitePoliciesForProcessSwap):
+    (API::Navigation::takeWebsitePoliciesForProcessSwap):
+    * UIProcess/WebPageProxy.cpp:
+    (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+    (WebKit::WebPageProxy::receivedPolicyDecision):
+    (WebKit::WebPageProxy::continueNavigationInNewProcess):
+    (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
+    * UIProcess/WebPageProxy.h:
+    
+    Tools:
+    
+    * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291606 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-22  Youenn Fablet  <[email protected]>
+
+            Website policies are not respected when doing COOP based process swap
+            https://bugs.webkit.org/show_bug.cgi?id=238036
+            <rdar://89616625>
+
+            Reviewed by Chris Dumez.
+
+            In case of normal process swap, we make use of website policies so everything is fine.
+            For COOP based process swap, this happens later on, at a point where we lost website policies.
+            To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
+            It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
+            We then set the website policies in the navigation object just before continuing the load in the same process,
+            as process swap may happen later when inspecting the response.
+            Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
+            Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.
+
+            Covered by API test.
+
+            * UIProcess/API/APINavigation.h:
+            (API::Navigation::setWebsitePoliciesForProcessSwap):
+            (API::Navigation::takeWebsitePoliciesForProcessSwap):
+            * UIProcess/WebPageProxy.cpp:
+            (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+            (WebKit::WebPageProxy::receivedPolicyDecision):
+            (WebKit::WebPageProxy::continueNavigationInNewProcess):
+            (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
+            * UIProcess/WebPageProxy.h:
+
+2022-04-19  Alan Coon  <[email protected]>
+
         Cherry-pick r291589. rdar://problem/90511155
 
     LayoutTests/imported/w3c:

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/API/APINavigation.h (293071 => 293072)


--- branches/safari-613-branch/Source/WebKit/UIProcess/API/APINavigation.h	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/API/APINavigation.h	2022-04-20 05:38:27 UTC (rev 293072)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "APIObject.h"
+#include "APIWebsitePolicies.h"
 #include "DataReference.h"
 #include "FrameInfoData.h"
 #include "NavigationActionData.h"
@@ -171,6 +172,9 @@
     void setIsLoadedWithNavigationShared(bool value) { m_isLoadedWithNavigationShared = value; }
     bool isLoadedWithNavigationShared() const { return m_isLoadedWithNavigationShared; }
 
+    void setWebsitePolicies(RefPtr<API::WebsitePolicies>&& policies) { m_websitePolicies = WTFMove(policies); }
+    API::WebsitePolicies* websitePolicies() { return m_websitePolicies.get(); }
+
 private:
     explicit Navigation(WebKit::WebNavigationState&);
     Navigation(WebKit::WebNavigationState&, WebKit::WebBackForwardListItem*);
@@ -197,6 +201,7 @@
     WebKit::WebContentMode m_effectiveContentMode { WebKit::WebContentMode::Recommended };
     WebKit::ProcessThrottler::TimedActivity m_clientNavigationActivity;
     bool m_isLoadedWithNavigationShared { false };
+    RefPtr<API::WebsitePolicies> m_websitePolicies;
 };
 
 } // namespace API

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (293071 => 293072)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-04-20 05:38:27 UTC (rev 293072)
@@ -3400,12 +3400,12 @@
 #endif
 }
 
-void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, const FrameInfoData& frameInfo, RefPtr<API::WebsitePolicies>&& policies, Ref<PolicyDecisionSender>&& sender)
+void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, const FrameInfoData& frameInfo, Ref<PolicyDecisionSender>&& sender)
 {
     WEBPAGEPROXY_RELEASE_LOG(Loading, "receivedNavigationPolicyDecision: frameID=%llu, navigationID=%llu, policyAction=%u", frame.frameID().toUInt64(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction);
 
     Ref<WebsiteDataStore> websiteDataStore = m_websiteDataStore.copyRef();
-    if (policies) {
+    if (auto* policies = navigation->websitePolicies()) {
         if (policies->websiteDataStore() && policies->websiteDataStore() != websiteDataStore.ptr()) {
             websiteDataStore = *policies->websiteDataStore();
             processSwapRequestedByClient = ProcessSwapRequestedByClient::Yes;
@@ -3415,18 +3415,18 @@
     }
 
     if (navigation && !navigation->userContentExtensionsEnabled()) {
-        if (!policies)
-            policies = API::WebsitePolicies::create();
-        policies->setContentBlockersEnabled(false);
+        if (!navigation->websitePolicies())
+            navigation->setWebsitePolicies(API::WebsitePolicies::create());
+        navigation->websitePolicies()->setContentBlockersEnabled(false);
     }
 
 #if ENABLE(DEVICE_ORIENTATION)
-    if (navigation && (!policies || policies->deviceOrientationAndMotionAccessState() == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
+    if (navigation && (!navigation->websitePolicies() || navigation->websitePolicies()->deviceOrientationAndMotionAccessState() == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
         auto deviceOrientationPermission = websiteDataStore->deviceOrientationAndMotionAccessController().cachedDeviceOrientationPermission(SecurityOriginData::fromURL(navigation->currentRequest().url()));
         if (deviceOrientationPermission != WebCore::DeviceOrientationOrMotionPermissionState::Prompt) {
-            if (!policies)
-                policies = API::WebsitePolicies::create();
-            policies->setDeviceOrientationAndMotionAccessState(deviceOrientationPermission);
+            if (!navigation->websitePolicies())
+                navigation->setWebsitePolicies(API::WebsitePolicies::create());
+            navigation->websitePolicies()->setDeviceOrientationAndMotionAccessState(deviceOrientationPermission);
         }
     }
 #endif
@@ -3440,7 +3440,7 @@
         policyAction = PolicyAction::Download;
 
     if (policyAction != PolicyAction::Use || !frame.isMainFrame() || !navigation) {
-        receivedPolicyDecision(policyAction, navigation, WTFMove(policies), WTFMove(navigationAction), WTFMove(sender));
+        receivedPolicyDecision(policyAction, navigation, navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
         return;
     }
 
@@ -3453,13 +3453,12 @@
         }
     }
 
-    m_isCaptivePortalModeExplicitlySet = (policies && policies->isCaptivePortalModeExplicitlySet()) || m_configuration->isCaptivePortalModeExplicitlySet();
-    auto captivePortalMode = (policies ? policies->captivePortalModeEnabled() : shouldEnableCaptivePortalMode()) ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
-    process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, captivePortalMode, frameInfo, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(),
-        policies = WTFMove(policies), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
+    m_isCaptivePortalModeExplicitlySet = (navigation->websitePolicies() && navigation->websitePolicies()->isCaptivePortalModeExplicitlySet()) || m_configuration->isCaptivePortalModeExplicitlySet();
+    auto captivePortalMode = (navigation->websitePolicies() ? navigation->websitePolicies()->captivePortalModeEnabled() : shouldEnableCaptivePortalMode()) ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
+    process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, captivePortalMode, frameInfo, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
         // If the navigation has been destroyed, then no need to proceed.
         if (isClosed() || !navigationState().hasNavigation(navigation->navigationID())) {
-            receivedPolicyDecision(policyAction, navigation.ptr(), WTFMove(policies), WTFMove(navigationAction), WTFMove(sender));
+            receivedPolicyDecision(policyAction, navigation.ptr(), navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
             return;
         }
 
@@ -3471,7 +3470,6 @@
         } else
             WEBPAGEPROXY_RELEASE_LOG(ProcessSwapping, "decidePolicyForNavigationAction: keep using process %i for navigation, reason=%" PUBLIC_LOG_STRING, processIdentifier(), reason.utf8().data());
 
-        std::optional<SandboxExtension::Handle> optionalHandle;
         if (shouldProcessSwap) {
             // Make sure the process to be used for the navigation does not get shutDown now due to destroying SuspendedPageProxy or ProvisionalPageProxy objects.
             auto preventNavigationProcessShutdown = processForNavigation->shutdownPreventingScope();
@@ -3489,24 +3487,28 @@
             if (suspendedPage && suspendedPage->pageIsClosedOrClosing())
                 suspendedPage = nullptr;
 
-            continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision, std::exchange(policies, nullptr));
-        } else {
-            auto item = navigation->reloadItem() ? navigation->reloadItem() : navigation->targetItem();
-            if (policyAction == PolicyAction::Use && item) {
-                auto fullURL = URL { URL(), item->url() };
-                if (fullURL.protocolIs("file"_s)) {
-                    SandboxExtension::Handle sandboxExtensionHandle;
-                    maybeInitializeSandboxExtensionHandle(processForNavigation.get(), fullURL, item->resourceDirectoryURL(), sandboxExtensionHandle);
-                    optionalHandle = WTFMove(sandboxExtensionHandle);
-                }
+            continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision);
+
+            receivedPolicyDecision(policyAction, navigation.ptr(), nullptr, WTFMove(navigationAction), WTFMove(sender), WillContinueLoadInNewProcess::Yes);
+            return;
+        }
+
+        auto item = navigation->reloadItem() ? navigation->reloadItem() : navigation->targetItem();
+        std::optional<SandboxExtension::Handle> optionalHandle;
+        if (policyAction == PolicyAction::Use && item) {
+            URL fullURL { item->url() };
+            if (fullURL.protocolIs("file"_s)) {
+                SandboxExtension::Handle sandboxExtensionHandle;
+                maybeInitializeSandboxExtensionHandle(processForNavigation.get(), fullURL, item->resourceDirectoryURL(), sandboxExtensionHandle);
+                optionalHandle = WTFMove(sandboxExtensionHandle);
             }
         }
 
-        receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? nullptr : WTFMove(policies), WTFMove(navigationAction), WTFMove(sender), WTFMove(optionalHandle), shouldProcessSwap ? WillContinueLoadInNewProcess::Yes : WillContinueLoadInNewProcess::No);
+        receivedPolicyDecision(policyAction, navigation.ptr(), navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender), WillContinueLoadInNewProcess::No, WTFMove(optionalHandle));
     });
 }
 
-void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, std::optional<SandboxExtension::Handle> sandboxExtensionHandle, WillContinueLoadInNewProcess willContinueLoadInNewProcess)
+void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional<SandboxExtension::Handle> sandboxExtensionHandle)
 {
     if (!hasRunningProcess()) {
         sender->send(PolicyDecision { sender->identifier(), isNavigatingToAppBoundDomain(), PolicyAction::Ignore, 0, std::nullopt, std::nullopt });
@@ -3596,7 +3598,7 @@
     m_provisionalPage = nullptr;
 }
 
-void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&& websitePolicies, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
+void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
 {
     WEBPAGEPROXY_RELEASE_LOG(Loading, "continueNavigationInNewProcess: newProcessPID=%i, hasSuspendedPage=%i", newProcess->processIdentifier(), !!suspendedPage);
     LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString());
@@ -3610,6 +3612,7 @@
         m_provisionalPage = nullptr;
     }
 
+    RefPtr websitePolicies = navigation.websitePolicies();
     bool isServerSideRedirect = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision && navigation.currentRequestIsRedirect();
     bool isProcessSwappingOnNavigationResponse = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted;
     m_provisionalPage = makeUnique<ProvisionalPageProxy>(*this, WTFMove(newProcess), WTFMove(suspendedPage), navigation.navigationID(), isServerSideRedirect, navigation.currentRequest(), processSwapRequestedByClient, isProcessSwappingOnNavigationResponse, websitePolicies.get());
@@ -5472,16 +5475,17 @@
     Ref listener = frame.setUpPolicyListenerProxy([this, protectedThis = Ref { *this }, frame = Ref { frame }, sender = WTFMove(sender), navigation, navigationAction, frameInfo, userDataObject = process->transformHandlesToObjects(userData.object()).get()] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, std::optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
         WEBPAGEPROXY_RELEASE_LOG(Loading, "decidePolicyForNavigationAction: listener called: frameID=%llu, navigationID=%llu, policyAction=%u, safeBrowsingWarning=%d, isAppBoundDomain=%d", frame->frameID().toUInt64(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction, !!safeBrowsingWarning, !!isAppBoundDomain);
 
-        auto completionHandler = [this, protectedThis, frame, frameInfo, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient, policies = RefPtr { policies }] (PolicyAction policyAction) mutable {
+        navigation->setWebsitePolicies(WTFMove(policies));
+        auto completionHandler = [this, protectedThis, frame, frameInfo, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient] (PolicyAction policyAction) mutable {
             if (frame->isMainFrame()) {
-                if (!policies) {
+                if (!navigation->websitePolicies()) {
                     if (auto* defaultPolicies = m_configuration->defaultWebsitePolicies())
-                        policies = defaultPolicies->copy();
+                        navigation->setWebsitePolicies(defaultPolicies->copy());
                 }
-                if (policies)
+                if (auto* policies = navigation->websitePolicies())
                     navigation->setEffectiveContentMode(effectiveContentModeAfterAdjustingPolicies(*policies, navigation->currentRequest()));
             }
-            receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, frameInfo, WTFMove(policies), WTFMove(sender));
+            receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, frameInfo, WTFMove(sender));
         };
 
 #if ENABLE(APP_BOUND_DOMAINS)
@@ -5739,7 +5743,7 @@
     else
         processForNavigation = m_process->processPool().processForRegistrableDomain(websiteDataStore(), responseDomain, m_process->captivePortalMode());
 
-    continueNavigationInNewProcess(*navigation, nullptr, processForNavigation.releaseNonNull(), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted, nullptr, existingNetworkResourceLoadIdentifierToResume);
+    continueNavigationInNewProcess(*navigation, nullptr, processForNavigation.releaseNonNull(), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted, existingNetworkResourceLoadIdentifierToResume);
     completionHandler(true);
 }
 

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.h (293071 => 293072)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.h	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.h	2022-04-20 05:38:27 UTC (rev 293072)
@@ -1248,8 +1248,8 @@
 
     class PolicyDecisionSender;
     enum class WillContinueLoadInNewProcess : bool { No, Yes };
-    void receivedPolicyDecision(WebCore::PolicyAction, API::Navigation*, RefPtr<API::WebsitePolicies>&&, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&&, Ref<PolicyDecisionSender>&&, std::optional<SandboxExtension::Handle> = { }, WillContinueLoadInNewProcess = WillContinueLoadInNewProcess::No);
-    void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, const FrameInfoData&, RefPtr<API::WebsitePolicies>&&, Ref<PolicyDecisionSender>&&);
+    void receivedPolicyDecision(WebCore::PolicyAction, API::Navigation*, RefPtr<API::WebsitePolicies>&&, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&&, Ref<PolicyDecisionSender>&&, WillContinueLoadInNewProcess = WillContinueLoadInNewProcess::No, std::optional<SandboxExtension::Handle> = { });
+    void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, const FrameInfoData&, Ref<PolicyDecisionSender>&&);
 
     void backForwardRemovedItem(const WebCore::BackForwardItemIdentifier&);
 
@@ -2511,7 +2511,7 @@
 
     void reportPageLoadResult(const WebCore::ResourceError& = { });
 
-    void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&&, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
+    void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
 
     void setNeedsFontAttributes(bool);
     void updateFontAttributesAfterEditorStateChange();

Modified: branches/safari-613-branch/Tools/ChangeLog (293071 => 293072)


--- branches/safari-613-branch/Tools/ChangeLog	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Tools/ChangeLog	2022-04-20 05:38:27 UTC (rev 293072)
@@ -1,3 +1,52 @@
+2022-04-19  Alan Coon  <[email protected]>
+
+        Cherry-pick r291606. rdar://problem/91446317
+
+    Website policies are not respected when doing COOP based process swap
+    https://bugs.webkit.org/show_bug.cgi?id=238036
+    <rdar://89616625>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebKit:
+    
+    In case of normal process swap, we make use of website policies so everything is fine.
+    For COOP based process swap, this happens later on, at a point where we lost website policies.
+    To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
+    It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
+    We then set the website policies in the navigation object just before continuing the load in the same process,
+    as process swap may happen later when inspecting the response.
+    Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
+    Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.
+    
+    Covered by API test.
+    
+    * UIProcess/API/APINavigation.h:
+    (API::Navigation::setWebsitePoliciesForProcessSwap):
+    (API::Navigation::takeWebsitePoliciesForProcessSwap):
+    * UIProcess/WebPageProxy.cpp:
+    (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+    (WebKit::WebPageProxy::receivedPolicyDecision):
+    (WebKit::WebPageProxy::continueNavigationInNewProcess):
+    (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
+    * UIProcess/WebPageProxy.h:
+    
+    Tools:
+    
+    * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291606 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-22  Youenn Fablet  <[email protected]>
+
+            Website policies are not respected when doing COOP based process swap
+            https://bugs.webkit.org/show_bug.cgi?id=238036
+            <rdar://89616625>
+
+            Reviewed by Chris Dumez.
+
+            * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
 2022-04-18  Kocsen Chung  <[email protected]>
 
         Cherry-pick r292401. rdar://problem/83168970

Modified: branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (293071 => 293072)


--- branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2022-04-20 05:38:22 UTC (rev 293071)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2022-04-20 05:38:27 UTC (rev 293072)
@@ -8258,3 +8258,152 @@
 }
 
 #endif
+
+#if PLATFORM(IOS_FAMILY)
+TEST(ProcessSwap, ContentModeInCaseOfCoopProcessSwap)
+{
+    using namespace TestWebKitAPI;
+
+    HTTPServer server({
+        { "/source.html", { "foo" } },
+        { "/destination.html", { { { "Content-Type", "text/html" }, { "Cross-Origin-Opener-Policy", "same-origin" } }, "bar" } },
+    }, HTTPServer::Protocol::Https);
+
+    auto processPoolConfiguration = psonProcessPoolConfiguration();
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+
+    auto webpagePreferences = adoptNS([[WKWebpagePreferences alloc] init]);
+    [webpagePreferences setPreferredContentMode:WKContentModeDesktop];
+    [webViewConfiguration setDefaultWebpagePreferences:webpagePreferences.get()];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    done = false;
+    [webView loadRequest:server.request("/source.html")];
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+
+    auto pid1 = [webView _webProcessIdentifier];
+
+    [webView loadRequest:server.request("/destination.html")];
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+
+    auto pid2 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, pid2);
+
+    [webView goBack]; // Back to source.html.
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+}
+
+TEST(ProcessSwap, ContentModeInCaseOfPSONThenCoopProcessSwap)
+{
+    using namespace TestWebKitAPI;
+
+    HTTPServer server1({
+        { "/source.html", { "foo" } },
+    }, HTTPServer::Protocol::Https);
+
+    HTTPServer server2({
+        { "/destination.html", { { { "Content-Type", "text/html" }, { "Cross-Origin-Opener-Policy", "same-origin" } }, "bar" } },
+    }, HTTPServer::Protocol::Http);
+
+    auto processPoolConfiguration = psonProcessPoolConfiguration();
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+
+    auto webpagePreferences = adoptNS([[WKWebpagePreferences alloc] init]);
+    [webpagePreferences setPreferredContentMode:WKContentModeDesktop];
+    [webViewConfiguration setDefaultWebpagePreferences:webpagePreferences.get()];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    done = false;
+    [webView loadRequest:server1.request("/source.html")];
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+
+    auto pid1 = [webView _webProcessIdentifier];
+
+    [webView loadRequest:server2.request("/destination.html")];
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+
+    auto pid2 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, pid2);
+
+    [webView goBack]; // Back to source.html.
+    Util::run(&done);
+    done = false;
+
+    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
+        done = true;
+
+        ASSERT_TRUE(!error);
+        NSString *userAgent = (NSString *)response;
+        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
+    }];
+    Util::run(&done);
+    done = false;
+}
+#endif // PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to