Title: [236069] trunk
Revision
236069
Author
[email protected]
Date
2018-09-17 10:15:07 -0700 (Mon, 17 Sep 2018)

Log Message

PSON: window.open() with 'noopener' should only process-swap cross-site, not cross-origin
https://bugs.webkit.org/show_bug.cgi?id=189602
<rdar://problem/44430549>

Reviewed by Geoff Garen.

Source/WebCore:

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::setTriggeringAction):
* loader/DocumentLoader.h:
* loader/FrameLoadRequest.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::loadWithDocumentLoader):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
(WebCore::FrameLoader::loadDifferentDocumentItem):
Move NavigationAction's opener setting to loadWithNavigationAction() as this is a better bottleneck.
Otherwise, we'd have to set it at several call sites. Also move the NavigationAction around instead
of copying it.

* loader/FrameLoader.h:
(WebCore::FrameLoader::loadWithNavigationAction):
* loader/NavigationAction.h:
(WebCore::NavigationAction::setShouldOpenExternalURLsPolicy):
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::createWindow):

Source/WebKit:

The following fixes were made to our process swap on navigation logic:
- Browsing contexts opened via window.open() with 'noopener' option now only same if
  they are cross-site, instead of doing a stricter cross-origin check.
- Support process swapping when opening a new window via <a target="_blank" rel="noopener">
  that is cross-site.

In order to support this, the following changes were made:
- Stop passing a 'isCrossOriginWindowOpenNavigation' flag to the UIProcess when navigating because:
  - This is specific to window.open() and does not apply to other windows opened by DOM
  - This forces the origin check to happens on WebContent process side instead of relying on the
    one in WebProcessPool in the UIProcess
- Pass the origin of the requester to the UIProcess when navigating, so that the WebProcessPool
  can use the requester's host for the cross-site check for the initial navigation in a new window
  created by DOM.
- Add 2 flags to WebPageProxy which indicate if the page was created by the DOM and if any provisional
  loads have been committed. The WebProcessPool uses theses flags to recognize initial loads in
  new windows created by the DOM, so that it uses the requester's origin for the cross-site check.

* Shared/NavigationActionData.cpp:
(WebKit::NavigationActionData::encode const):
(WebKit::NavigationActionData::decode):
* Shared/NavigationActionData.h:
* UIProcess/API/APINavigation.h:
(API::Navigation::setRequesterOrigin):
(API::Navigation::requesterOrigin const):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::continueNavigationInNewProcess):
(WebKit::WebPageProxy::didCommitLoadForFrame):
(WebKit::WebPageProxy::decidePolicyForNavigationAction):
(WebKit::WebPageProxy::createNewPage):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::setOpenedByDOM):
(WebKit::WebPageProxy::openedByDOM const):
(WebKit::WebPageProxy::hasCommittedAnyProvisionalLoads const):
* UIProcess/WebProcessPool.cpp:
(WebKit::shouldUseSameProcessBasedOnURLs):
(WebKit::WebProcessPool::processForNavigationInternal):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (236068 => 236069)


--- trunk/Source/WebCore/ChangeLog	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/ChangeLog	2018-09-17 17:15:07 UTC (rev 236069)
@@ -1,3 +1,35 @@
+2018-09-17  Chris Dumez  <[email protected]>
+
+        PSON: window.open() with 'noopener' should only process-swap cross-site, not cross-origin
+        https://bugs.webkit.org/show_bug.cgi?id=189602
+        <rdar://problem/44430549>
+
+        Reviewed by Geoff Garen.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::setTriggeringAction):
+        * loader/DocumentLoader.h:
+        * loader/FrameLoadRequest.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        (WebCore::FrameLoader::loadWithDocumentLoader):
+        (WebCore::FrameLoader::loadPostRequest):
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
+        (WebCore::FrameLoader::loadDifferentDocumentItem):
+        Move NavigationAction's opener setting to loadWithNavigationAction() as this is a better bottleneck.
+        Otherwise, we'd have to set it at several call sites. Also move the NavigationAction around instead
+        of copying it.
+
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        * loader/NavigationAction.h:
+        (WebCore::NavigationAction::setShouldOpenExternalURLsPolicy):
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::createWindow):
+
 2018-09-17  Darin Adler  <[email protected]>
 
         Use OpaqueJSString rather than JSRetainPtr inside WebKit

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (236068 => 236069)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -1980,9 +1980,10 @@
     m_applicationCacheHost->stopDeferringEvents();
 }
 
-void DocumentLoader::setTriggeringAction(const NavigationAction& action)
+void DocumentLoader::setTriggeringAction(NavigationAction&& action)
 {
-    m_triggeringAction = action.copyWithShouldOpenExternalURLsPolicy(m_frame ? shouldOpenExternalURLsPolicyToPropagate() : m_shouldOpenExternalURLsPolicy);
+    m_triggeringAction = WTFMove(action);
+    m_triggeringAction.setShouldOpenExternalURLsPolicy(m_frame ? shouldOpenExternalURLsPolicyToPropagate() : m_shouldOpenExternalURLsPolicy);
 }
 
 ShouldOpenExternalURLsPolicy DocumentLoader::shouldOpenExternalURLsPolicyToPropagate() const

Modified: trunk/Source/WebCore/loader/DocumentLoader.h (236068 => 236069)


--- trunk/Source/WebCore/loader/DocumentLoader.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/DocumentLoader.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -214,7 +214,7 @@
     const Vector<ResourceResponse>& responses() const { return m_responses; }
 
     const NavigationAction& triggeringAction() const { return m_triggeringAction; }
-    void setTriggeringAction(const NavigationAction&);
+    void setTriggeringAction(NavigationAction&&);
     void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
     void setLastCheckedRequest(ResourceRequest&& request) { m_lastCheckedRequest = WTFMove(request); }
     const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }

Modified: trunk/Source/WebCore/loader/FrameLoadRequest.h (236068 => 236069)


--- trunk/Source/WebCore/loader/FrameLoadRequest.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/FrameLoadRequest.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -88,9 +88,6 @@
 
     InitiatedByMainFrame initiatedByMainFrame() const { return m_initiatedByMainFrame; }
 
-    void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
-    bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
-
     bool isSystemPreview() const { return m_systemPreviewInfo.isSystemPreview; }
     const IntRect& systemPreviewRect() const { return m_systemPreviewInfo.systemPreviewRect; }
 
@@ -112,7 +109,6 @@
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
     AtomicString m_downloadAttribute;
     InitiatedByMainFrame m_initiatedByMainFrame { InitiatedByMainFrame::Unknown };
-    bool m_isCrossOriginWindowOpenNavigation { false };
     SystemPreviewInfo m_systemPreviewInfo;
     ShouldSkipSafeBrowsingCheck m_shouldSkipSafeBrowsingCheck { ShouldSkipSafeBrowsingCheck::No };
 };

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (236068 => 236069)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -1363,16 +1363,9 @@
         return;
 
     NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
-    action.setIsCrossOriginWindowOpenNavigation(frameLoadRequest.isCrossOriginWindowOpenNavigation());
     if (m_frame.page() && m_frame.page()->openedViaWindowOpenWithOpener())
         action.setOpenedViaWindowOpenWithOpener();
     action.setHasOpenedFrames(!m_openedFrames.isEmpty());
-    if (auto* opener = this->opener()) {
-        auto pageID = opener->loader().client().pageID();
-        auto frameID = opener->loader().client().frameID();
-        if (pageID && frameID)
-            action.setOpener(std::make_pair(*pageID, *frameID));
-    }
 
     if (!targetFrame && !frameName.isEmpty()) {
         action = "" frameLoadRequest));
@@ -1392,7 +1385,7 @@
     // exactly the same so pages with '#' links and DHTML side effects
     // work properly.
     if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, newLoadType, newURL)) {
-        oldDocumentLoader->setTriggeringAction(action);
+        oldDocumentLoader->setTriggeringAction(WTFMove(action));
         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
         policyChecker().stopCheck();
         policyChecker().setLoadType(newLoadType);
@@ -1410,7 +1403,7 @@
     if (isSystemPreview)
         request.setSystemPreviewRect(frameLoadRequest.systemPreviewRect());
 #endif
-    loadWithNavigationAction(request, action, lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, frameLoadRequest.shouldSkipSafeBrowsingCheck(), [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
+    loadWithNavigationAction(request, WTFMove(action), lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, frameLoadRequest.shouldSkipSafeBrowsingCheck(), [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
         if (isRedirect) {
             m_quickRedirectComing = false;
             if (m_provisionalDocumentLoader)
@@ -1475,7 +1468,7 @@
     load(loader.get(), request.shouldSkipSafeBrowsingCheck());
 }
 
-void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, CompletionHandler<void()>&& completionHandler)
+void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, CompletionHandler<void()>&& completionHandler)
 {
     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
@@ -1483,7 +1476,14 @@
     if (lockHistory == LockHistory::Yes && m_documentLoader)
         loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
 
-    loader->setTriggeringAction(action);
+    if (auto* opener = this->opener()) {
+        auto pageID = opener->loader().client().pageID();
+        auto frameID = opener->loader().client().frameID();
+        if (pageID && frameID)
+            action.setOpener(std::make_pair(*pageID, *frameID));
+    }
+
+    loader->setTriggeringAction(WTFMove(action));
     if (m_documentLoader)
         loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
 
@@ -1568,7 +1568,7 @@
         RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
         NavigationAction action { *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission };
 
-        oldDocumentLoader->setTriggeringAction(action);
+        oldDocumentLoader->setTriggeringAction(WTFMove(action));
         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
         policyChecker().stopCheck();
         policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { }  /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) {
@@ -2928,7 +2928,7 @@
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
         if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
-            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck::No, WTFMove(completionHandler));
+            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck::No, WTFMove(completionHandler));
             return;
         }
 
@@ -2941,7 +2941,7 @@
 
     // must grab this now, since this load may stop the previous load and clear this flag
     bool isRedirect = m_quickRedirectComing;
-    loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, request.shouldSkipSafeBrowsingCheck(), [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
+    loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, request.shouldSkipSafeBrowsingCheck(), [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
         if (isRedirect) {
             m_quickRedirectComing = false;
             if (m_provisionalDocumentLoader)
@@ -3403,7 +3403,7 @@
     }
 
     NavigationAction newAction { *frame->document(), request, InitiatedByMainFrame::Unknown, NavigationType::Other, action.shouldOpenExternalURLsPolicy() };
-    mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
+    mainFrame->loader().loadWithNavigationAction(request, WTFMove(newAction), LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
 }
 
 void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
@@ -3687,7 +3687,7 @@
 
     action.setTargetBackForwardItem(item);
 
-    loadWithNavigationAction(request, action, LockHistory::No, loadType, { }, AllowNavigationToInvalidURL::Yes);
+    loadWithNavigationAction(request, WTFMove(action), LockHistory::No, loadType, { }, AllowNavigationToInvalidURL::Yes);
 }
 
 // Loads content into this frame, as specified by history item

Modified: trunk/Source/WebCore/loader/FrameLoader.h (236068 => 236069)


--- trunk/Source/WebCore/loader/FrameLoader.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -372,7 +372,7 @@
     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, ShouldSkipSafeBrowsingCheck = ShouldSkipSafeBrowsingCheck::No, CompletionHandler<void()>&& = [] { }); // Calls continueLoadAfterNavigationPolicy
     void load(DocumentLoader&, ShouldSkipSafeBrowsingCheck); // Calls loadWithDocumentLoader
 
-    void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck = ShouldSkipSafeBrowsingCheck::No, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
+    void loadWithNavigationAction(const ResourceRequest&, NavigationAction&&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldSkipSafeBrowsingCheck = ShouldSkipSafeBrowsingCheck::No, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
 
     void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
     void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);

Modified: trunk/Source/WebCore/loader/NavigationAction.h (236068 => 236069)


--- trunk/Source/WebCore/loader/NavigationAction.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/NavigationAction.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -111,6 +111,7 @@
     RefPtr<UserGestureToken> userGestureToken() const { return m_userGestureToken; }
 
     ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const { return m_shouldOpenExternalURLsPolicy; }
+    void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy policy) {  m_shouldOpenExternalURLsPolicy = policy; }
     InitiatedByMainFrame initiatedByMainFrame() const { return m_initiatedByMainFrame; }
 
     const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
@@ -117,9 +118,6 @@
 
     bool treatAsSameOriginNavigation() const { return m_treatAsSameOriginNavigation; }
 
-    void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
-    bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
-
     void setOpener(std::optional<PageIDAndFrameIDPair>&& opener) { m_opener = WTFMove(opener); }
     const std::optional<PageIDAndFrameIDPair>& opener() const { return m_opener; }
 
@@ -145,7 +143,6 @@
     RefPtr<UserGestureToken> m_userGestureToken { UserGestureIndicator::currentUserGesture() };
     AtomicString m_downloadAttribute;
     bool m_treatAsSameOriginNavigation;
-    bool m_isCrossOriginWindowOpenNavigation { false };
     bool m_hasOpenedFrames { false };
     bool m_openedViaWindowOpenWithOpener { false };
     std::optional<PageIDAndFrameIDPair> m_opener;

Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (236068 => 236069)


--- trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -103,7 +103,7 @@
     NavigationAction action = ""
     if (action.isEmpty()) {
         action = "" { *m_frame.document(), request, InitiatedByMainFrame::Unknown, NavigationType::Other, loader->shouldOpenExternalURLsPolicyToPropagate() };
-        loader->setTriggeringAction(action);
+        loader->setTriggeringAction(NavigationAction { action });
     }
 
     // Don't ask more than once for the same request or if we are loading an empty URL.

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (236068 => 236069)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -2282,8 +2282,6 @@
         ResourceRequest resourceRequest { completedURL, referrer, ResourceRequestCachePolicy::UseProtocolCachePolicy };
         FrameLoader::addSameSiteInfoToRequestIfNeeded(resourceRequest, openerFrame.document());
         FrameLoadRequest frameLoadRequest { *activeWindow.document(), activeWindow.document()->securityOrigin(), resourceRequest, "_self"_s, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate(), initiatedByMainFrame };
-        if (openerFrame.document() && !protocolHostAndPortAreEqual(openerFrame.document()->url(), frameLoadRequest.resourceRequest().url()))
-            frameLoadRequest.setIsCrossOriginWindowOpenNavigation(true);
         newFrame->loader().changeLocation(WTFMove(frameLoadRequest));
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)

Modified: trunk/Source/WebKit/ChangeLog (236068 => 236069)


--- trunk/Source/WebKit/ChangeLog	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/ChangeLog	2018-09-17 17:15:07 UTC (rev 236069)
@@ -1,3 +1,51 @@
+2018-09-17  Chris Dumez  <[email protected]>
+
+        PSON: window.open() with 'noopener' should only process-swap cross-site, not cross-origin
+        https://bugs.webkit.org/show_bug.cgi?id=189602
+        <rdar://problem/44430549>
+
+        Reviewed by Geoff Garen.
+
+        The following fixes were made to our process swap on navigation logic:
+        - Browsing contexts opened via window.open() with 'noopener' option now only same if
+          they are cross-site, instead of doing a stricter cross-origin check.
+        - Support process swapping when opening a new window via <a target="_blank" rel="noopener">
+          that is cross-site.
+
+        In order to support this, the following changes were made:
+        - Stop passing a 'isCrossOriginWindowOpenNavigation' flag to the UIProcess when navigating because:
+          - This is specific to window.open() and does not apply to other windows opened by DOM
+          - This forces the origin check to happens on WebContent process side instead of relying on the
+            one in WebProcessPool in the UIProcess
+        - Pass the origin of the requester to the UIProcess when navigating, so that the WebProcessPool
+          can use the requester's host for the cross-site check for the initial navigation in a new window
+          created by DOM.
+        - Add 2 flags to WebPageProxy which indicate if the page was created by the DOM and if any provisional
+          loads have been committed. The WebProcessPool uses theses flags to recognize initial loads in
+          new windows created by the DOM, so that it uses the requester's origin for the cross-site check.
+
+        * Shared/NavigationActionData.cpp:
+        (WebKit::NavigationActionData::encode const):
+        (WebKit::NavigationActionData::decode):
+        * Shared/NavigationActionData.h:
+        * UIProcess/API/APINavigation.h:
+        (API::Navigation::setRequesterOrigin):
+        (API::Navigation::requesterOrigin const):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::continueNavigationInNewProcess):
+        (WebKit::WebPageProxy::didCommitLoadForFrame):
+        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+        (WebKit::WebPageProxy::createNewPage):
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::setOpenedByDOM):
+        (WebKit::WebPageProxy::openedByDOM const):
+        (WebKit::WebPageProxy::hasCommittedAnyProvisionalLoads const):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::shouldUseSameProcessBasedOnURLs):
+        (WebKit::WebProcessPool::processForNavigationInternal):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+
 2018-09-17  Alexey Proskuryakov  <[email protected]>
 
         Revert https://trac.webkit.org/r235910, because the new test times out.

Modified: trunk/Source/WebKit/Shared/NavigationActionData.cpp (236068 => 236069)


--- trunk/Source/WebKit/Shared/NavigationActionData.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/Shared/NavigationActionData.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -46,10 +46,10 @@
     encoder << clickLocationInRootViewCoordinates;
     encoder << isRedirect;
     encoder << treatAsSameOriginNavigation;
-    encoder << isCrossOriginWindowOpenNavigation;
     encoder << hasOpenedFrames;
     encoder << openedViaWindowOpenWithOpener;
     encoder << opener;
+    encoder << requesterOrigin;
     encoder << targetBackForwardItemIdentifier;
 }
 
@@ -104,11 +104,6 @@
     if (!treatAsSameOriginNavigation)
         return std::nullopt;
 
-    std::optional<bool> isCrossOriginWindowOpenNavigation;
-    decoder >> isCrossOriginWindowOpenNavigation;
-    if (!isCrossOriginWindowOpenNavigation)
-        return std::nullopt;
-
     std::optional<bool> hasOpenedFrames;
     decoder >> hasOpenedFrames;
     if (!hasOpenedFrames)
@@ -124,6 +119,11 @@
     if (!opener)
         return std::nullopt;
 
+    std::optional<WebCore::SecurityOriginData> requesterOrigin;
+    decoder >> requesterOrigin;
+    if (!opener)
+        return std::nullopt;
+
     std::optional<std::optional<WebCore::BackForwardItemIdentifier>> targetBackForwardItemIdentifier;
     decoder >> targetBackForwardItemIdentifier;
     if (!targetBackForwardItemIdentifier)
@@ -131,7 +131,8 @@
         
     return {{ WTFMove(navigationType), WTFMove(modifiers), WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier),
         WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates),
-        WTFMove(*isRedirect), *treatAsSameOriginNavigation, *isCrossOriginWindowOpenNavigation, *hasOpenedFrames, *openedViaWindowOpenWithOpener, WTFMove(*opener), WTFMove(*targetBackForwardItemIdentifier) }};
+        WTFMove(*isRedirect), *treatAsSameOriginNavigation, *hasOpenedFrames, *openedViaWindowOpenWithOpener, WTFMove(*opener), WTFMove(*requesterOrigin),
+        WTFMove(*targetBackForwardItemIdentifier) }};
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Shared/NavigationActionData.h (236068 => 236069)


--- trunk/Source/WebKit/Shared/NavigationActionData.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/Shared/NavigationActionData.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -29,6 +29,7 @@
 #include <WebCore/BackForwardItemIdentifier.h>
 #include <WebCore/FloatPoint.h>
 #include <WebCore/FrameLoaderTypes.h>
+#include <WebCore/SecurityOriginData.h>
 
 namespace IPC {
 class Decoder;
@@ -52,10 +53,10 @@
     WebCore::FloatPoint clickLocationInRootViewCoordinates;
     bool isRedirect { false };
     bool treatAsSameOriginNavigation { false };
-    bool isCrossOriginWindowOpenNavigation { false };
     bool hasOpenedFrames { false };
     bool openedViaWindowOpenWithOpener { false };
     std::optional<std::pair<uint64_t, uint64_t>> opener;
+    WebCore::SecurityOriginData requesterOrigin;
     std::optional<WebCore::BackForwardItemIdentifier> targetBackForwardItemIdentifier;
 };
 

Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (236068 => 236069)


--- trunk/Source/WebKit/UIProcess/API/APINavigation.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -29,6 +29,7 @@
 #include "WebBackForwardListItem.h"
 #include <WebCore/Process.h>
 #include <WebCore/ResourceRequest.h>
+#include <WebCore/SecurityOriginData.h>
 #include <wtf/Ref.h>
 
 namespace WebCore {
@@ -88,9 +89,6 @@
     void setTreatAsSameOriginNavigation(bool value) { m_treatAsSameOriginNavigation = value; }
     bool treatAsSameOriginNavigation() const { return m_treatAsSameOriginNavigation; }
 
-    void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
-    bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
-
     void setHasOpenedFrames(bool value) { m_hasOpenedFrames = value; }
     bool hasOpenedFrames() const { return m_hasOpenedFrames; }
 
@@ -100,6 +98,9 @@
     void setOpener(const std::optional<std::pair<uint64_t, uint64_t>>& opener) { m_opener = opener; }
     const std::optional<std::pair<uint64_t, uint64_t>>& opener() const { return m_opener; }
 
+    void setRequesterOrigin(const WebCore::SecurityOriginData& origin) { m_requesterOrigin = origin; }
+    const WebCore::SecurityOriginData& requesterOrigin() const { return m_requesterOrigin; }
+
 #if !LOG_DISABLED
     const char* loggingString() const;
 #endif
@@ -122,10 +123,10 @@
     RefPtr<WebKit::WebBackForwardListItem> m_fromItem;
     std::optional<WebCore::FrameLoadType> m_backForwardFrameLoadType;
     bool m_treatAsSameOriginNavigation { false };
-    bool m_isCrossOriginWindowOpenNavigation { false };
     bool m_hasOpenedFrames { false };
     bool m_openedViaWindowOpenWithOpener { false };
     std::optional<std::pair<uint64_t, uint64_t>> m_opener;
+    WebCore::SecurityOriginData m_requesterOrigin;
 };
 
 } // namespace API

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (236068 => 236069)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -2552,7 +2552,8 @@
         };
     }
 
-    if (!navigation.isCrossOriginWindowOpenNavigation() || !navigatedFrameIdentifierInPreviousProcess)
+    bool isInitialNavigationInNewWindow = openedByDOM() && !hasCommittedAnyProvisionalLoads();
+    if (!isInitialNavigationInNewWindow || !navigatedFrameIdentifierInPreviousProcess)
         return;
 
     m_mainFrameWindowCreationHandler = [this, previousProcess = WTFMove(previousProcess), navigatedFrameIdentifierInPreviousProcess = *navigatedFrameIdentifierInPreviousProcess](const GlobalWindowIdentifier& windowIdentifier) {
@@ -3657,6 +3658,7 @@
     if (frame->isMainFrame() && navigationID)
         navigation = &navigationState().navigation(navigationID);
 
+    m_hasCommittedAnyProvisionalLoads = true;
     m_process->didCommitProvisionalLoad();
 
 #if PLATFORM(IOS)
@@ -4049,11 +4051,11 @@
     navigation->setCurrentRequest(ResourceRequest(request), m_process->coreProcessIdentifier());
     navigation->setCurrentRequestIsRedirect(navigationActionData.isRedirect);
     navigation->setTreatAsSameOriginNavigation(navigationActionData.treatAsSameOriginNavigation);
-    navigation->setIsCrossOriginWindowOpenNavigation(navigationActionData.isCrossOriginWindowOpenNavigation);
     navigation->setHasOpenedFrames(navigationActionData.hasOpenedFrames);
     if (navigationActionData.openedViaWindowOpenWithOpener)
         navigation->setOpenedViaWindowOpenWithOpener();
     navigation->setOpener(navigationActionData.opener);
+    navigation->setRequesterOrigin(navigationActionData.requesterOrigin);
 
 #if ENABLE(CONTENT_FILTERING)
     if (frame->didHandleContentFilterUnblockNavigation(request))
@@ -4277,6 +4279,8 @@
             return;
         }
 
+        newPage->setOpenedByDOM();
+
         reply(newPage->pageID(), newPage->creationParameters());
 
         WebsiteDataStore::cloneSessionData(*this, *newPage);

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (236068 => 236069)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-09-17 17:15:07 UTC (rev 236069)
@@ -440,6 +440,11 @@
     bool tryClose();
     bool isClosed() const { return m_isClosed; }
 
+    void setOpenedByDOM() { m_openedByDOM = true; }
+    bool openedByDOM() const { return m_openedByDOM; }
+
+    bool hasCommittedAnyProvisionalLoads() const { return m_hasCommittedAnyProvisionalLoads; }
+
     void setIsUsingHighPerformanceWebGL(bool value) { m_isUsingHighPerformanceWebGL = value; }
     bool isUsingHighPerformanceWebGL() const { return m_isUsingHighPerformanceWebGL; }
 
@@ -2211,6 +2216,8 @@
 #endif
 
     bool m_isUsingHighPerformanceWebGL { false };
+    bool m_openedByDOM { false };
+    bool m_hasCommittedAnyProvisionalLoads { false };
 
     HashMap<String, Ref<WebURLSchemeHandler>> m_urlSchemeHandlersByScheme;
     HashMap<uint64_t, Ref<WebURLSchemeHandler>> m_urlSchemeHandlersByIdentifier;

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (236068 => 236069)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -2142,26 +2142,15 @@
         return page.process();
     }
 
-    if (navigation.isCrossOriginWindowOpenNavigation()) {
-        if (navigation.opener() && !m_configuration->processSwapsOnWindowOpenWithOpener()) {
-            reason = "Browsing context has an opener"_s;
-            return page.process();
-        }
-
-        reason = "Initial navigation is cross-site in a newly opened window"_s;
-        action = ""
-        return createNewWebProcess(page.websiteDataStore());
-    }
-
     // FIXME: We should support process swap when a window has been opened via window.open() without 'noopener'.
     // The issue is that the opener has a handle to the WindowProxy.
-    if (navigation.openedViaWindowOpenWithOpener()) {
+    if (navigation.openedViaWindowOpenWithOpener() && !m_configuration->processSwapsOnWindowOpenWithOpener()) {
         reason = "Browsing context been opened via window.open() without 'noopener'"_s;
         return page.process();
     }
 
     // FIXME: We should support process swap when a window has an opener.
-    if (navigation.opener()) {
+    if (navigation.opener() && !m_configuration->processSwapsOnWindowOpenWithOpener()) {
         reason = "Browsing context has an opener"_s;
         return page.process();
     }
@@ -2197,7 +2186,12 @@
             return page.process();
         }
 
-        auto url = "" { ParsedURLString, page.pageLoadState().url() };
+        bool isInitialLoadInNewWindowOpenedByDOM = page.openedByDOM() && !page.hasCommittedAnyProvisionalLoads();
+        URL url;
+        if (isInitialLoadInNewWindowOpenedByDOM && !navigation.requesterOrigin().isEmpty())
+            url = "" { URL(), navigation.requesterOrigin().toString() };
+        else
+            url = "" { ParsedURLString, page.pageLoadState().url() };
         if (!url.isValid() || !targetURL.isValid() || url.isEmpty() || url.isBlankURL() || registrableDomainsAreEqual(url, targetURL)) {
             reason = "Navigation is same-site"_s;
             return page.process();

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (236068 => 236069)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2018-09-17 17:15:07 UTC (rev 236069)
@@ -866,10 +866,11 @@
     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
     navigationActionData.isRedirect = !redirectResponse.isNull();
     navigationActionData.treatAsSameOriginNavigation = navigationAction.treatAsSameOriginNavigation();
-    navigationActionData.isCrossOriginWindowOpenNavigation = navigationAction.isCrossOriginWindowOpenNavigation();
     navigationActionData.hasOpenedFrames = navigationAction.hasOpenedFrames();
     navigationActionData.openedViaWindowOpenWithOpener = navigationAction.openedViaWindowOpenWithOpener();
     navigationActionData.opener = navigationAction.opener();
+    if (auto& requester = navigationAction.requester())
+        navigationActionData.requesterOrigin = requester->securityOrigin().data();
     navigationActionData.targetBackForwardItemIdentifier = navigationAction.targetBackForwardItemIdentifier();
 
     WebCore::Frame* coreFrame = m_frame->coreFrame();

Modified: trunk/Tools/ChangeLog (236068 => 236069)


--- trunk/Tools/ChangeLog	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Tools/ChangeLog	2018-09-17 17:15:07 UTC (rev 236069)
@@ -1,3 +1,15 @@
+2018-09-17  Chris Dumez  <[email protected]>
+
+        PSON: window.open() with 'noopener' should only process-swap cross-site, not cross-origin
+        https://bugs.webkit.org/show_bug.cgi?id=189602
+        <rdar://problem/44430549>
+
+        Reviewed by Geoff Garen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
 2018-09-17  Philippe Normand  <[email protected]>
 
         [JHBuild] Update to GStreamer 1.14.3

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (236068 => 236069)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2018-09-17 17:11:15 UTC (rev 236068)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2018-09-17 17:15:07 UTC (rev 236069)
@@ -247,7 +247,7 @@
 
 #if PLATFORM(MAC)
 
-static const char* windowOpenCrossOriginNoOpenerTestBytes = R"PSONRESOURCE(
+static const char* windowOpenCrossSiteNoOpenerTestBytes = R"PSONRESOURCE(
 <script>
 window._onload_ = function() {
     window.open("pson://www.apple.com/main.html", "_blank", "noopener");
@@ -255,15 +255,23 @@
 </script>
 )PSONRESOURCE";
 
-static const char* windowOpenCrossOriginWithOpenerTestBytes = R"PSONRESOURCE(
+static const char* windowOpenCrossOriginButSameSiteNoOpenerTestBytes = R"PSONRESOURCE(
 <script>
 window._onload_ = function() {
+    window.open("pson://www.webkit.org:8080/main.html", "_blank", "noopener");
+}
+</script>
+)PSONRESOURCE";
+
+static const char* windowOpenCrossSiteWithOpenerTestBytes = R"PSONRESOURCE(
+<script>
+window._onload_ = function() {
     window.open("pson://www.apple.com/main.html");
 }
 </script>
 )PSONRESOURCE";
 
-static const char* windowOpenSameOriginNoOpenerTestBytes = R"PSONRESOURCE(
+static const char* windowOpenSameSiteNoOpenerTestBytes = R"PSONRESOURCE(
 <script>
 window._onload_ = function() {
     if (!opener)
@@ -272,6 +280,33 @@
 </script>
 )PSONRESOURCE";
 
+static const char* targetBlankCrossSiteWithOpenerTestBytes = R"PSONRESOURCE(
+<a id="testLink" target="_blank" href=""
+<script>
+window._onload_ = function() {
+    testLink.click();
+}
+</script>
+)PSONRESOURCE";
+
+static const char* targetBlankCrossSiteNoOpenerTestBytes = R"PSONRESOURCE(
+<a id="testLink" target="_blank" href="" rel="noopener">Link</a>
+<script>
+window._onload_ = function() {
+    testLink.click();
+}
+</script>
+)PSONRESOURCE";
+
+static const char* targetBlankSameSiteNoOpenerTestBytes = R"PSONRESOURCE(
+<a id="testLink" target="_blank" href="" rel="noopener">Link</a>
+<script>
+window._onload_ = function() {
+    testLink.click();
+}
+</script>
+)PSONRESOURCE";
+
 #endif // PLATFORM(MAC)
 
 TEST(ProcessSwap, Basic)
@@ -479,7 +514,7 @@
 
 #if PLATFORM(MAC)
 
-TEST(ProcessSwap, CrossOriginWindowOpenNoOpener)
+TEST(ProcessSwap, CrossSiteWindowOpenNoOpener)
 {
     auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
     processPoolConfiguration.get().processSwapsOnNavigation = YES;
@@ -488,7 +523,7 @@
     auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [webViewConfiguration setProcessPool:processPool.get()];
     auto handler = adoptNS([[PSONScheme alloc] init]);
-    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenCrossOriginNoOpenerTestBytes];
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenCrossSiteNoOpenerTestBytes];
     [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
@@ -519,10 +554,50 @@
     EXPECT_NE(pid1, pid2);
 }
 
-TEST(ProcessSwap, CrossOriginWindowOpenWithOpener)
+TEST(ProcessSwap, CrossOriginButSameSiteWindowOpenNoOpener)
 {
     auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
     processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenCrossOriginButSameSiteNoOpenerTestBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+    [webView setUIDelegate:uiDelegate.get()];
+
+    numberOfDecidePolicyCalls = 0;
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    TestWebKitAPI::Util::run(&didCreateWebView);
+    didCreateWebView = false;
+
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_EQ(2, numberOfDecidePolicyCalls);
+
+    auto pid1 = [webView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid1);
+    auto pid2 = [createdWebView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid2);
+
+    EXPECT_EQ(pid1, pid2);
+}
+
+TEST(ProcessSwap, CrossSiteWindowOpenWithOpener)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
     processPoolConfiguration.get().processSwapsOnWindowOpenWithOpener = YES;
     auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
 
@@ -529,7 +604,7 @@
     auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [webViewConfiguration setProcessPool:processPool.get()];
     auto handler = adoptNS([[PSONScheme alloc] init]);
-    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenCrossOriginWithOpenerTestBytes];
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenCrossSiteWithOpenerTestBytes];
     [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
@@ -560,7 +635,7 @@
     EXPECT_NE(pid1, pid2);
 }
 
-TEST(ProcessSwap, SameOriginWindowOpenNoOpener)
+TEST(ProcessSwap, SameSiteWindowOpenNoOpener)
 {
     auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
     processPoolConfiguration.get().processSwapsOnNavigation = YES;
@@ -568,7 +643,7 @@
 
     auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [webViewConfiguration setProcessPool:processPool.get()];
-    auto handler = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenSameOriginNoOpenerTestBytes]);
+    auto handler = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenSameSiteNoOpenerTestBytes]);
     [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
 
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
@@ -599,6 +674,126 @@
     EXPECT_EQ(pid1, pid2);
 }
 
+TEST(ProcessSwap, CrossSiteBlankTargetWithOpener)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:targetBlankCrossSiteWithOpenerTestBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+    [webView setUIDelegate:uiDelegate.get()];
+
+    numberOfDecidePolicyCalls = 0;
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    TestWebKitAPI::Util::run(&didCreateWebView);
+    didCreateWebView = false;
+
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_EQ(3, numberOfDecidePolicyCalls);
+
+    auto pid1 = [webView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid1);
+    auto pid2 = [createdWebView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid2);
+
+    EXPECT_EQ(pid1, pid2);
+}
+
+TEST(ProcessSwap, CrossSiteBlankTargetNoOpener)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:targetBlankCrossSiteNoOpenerTestBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+    [webView setUIDelegate:uiDelegate.get()];
+
+    numberOfDecidePolicyCalls = 0;
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    TestWebKitAPI::Util::run(&didCreateWebView);
+    didCreateWebView = false;
+
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_EQ(3, numberOfDecidePolicyCalls);
+
+    auto pid1 = [webView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid1);
+    auto pid2 = [createdWebView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid2);
+
+    EXPECT_NE(pid1, pid2);
+}
+
+TEST(ProcessSwap, SameSiteBlankTargetNoOpener)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:targetBlankSameSiteNoOpenerTestBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+    [webView setUIDelegate:uiDelegate.get()];
+
+    numberOfDecidePolicyCalls = 0;
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    TestWebKitAPI::Util::run(&didCreateWebView);
+    didCreateWebView = false;
+
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_EQ(3, numberOfDecidePolicyCalls);
+
+    auto pid1 = [webView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid1);
+    auto pid2 = [createdWebView _webProcessIdentifier];
+    EXPECT_TRUE(!!pid2);
+
+    EXPECT_EQ(pid1, pid2);
+}
+
 #endif // PLATFORM(MAC)
 
 TEST(ProcessSwap, ServerRedirectFromNewWebView)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to