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)