Diff
Modified: trunk/LayoutTests/ChangeLog (284609 => 284610)
--- trunk/LayoutTests/ChangeLog 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/ChangeLog 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,3 +1,18 @@
+2021-10-21 Chris Dumez <[email protected]>
+
+ WebKit should process-swap for initial navigation of a popup if it has no opener
+ https://bugs.webkit.org/show_bug.cgi?id=231990
+ <rdar://84425504>
+
+ Reviewed by Brent Fulgham.
+
+ * fast/dom/open-and-close-by-DOM.html:
+ The test is relying on testRunner.windowCount(), which is only able to count windows inside the
+ current WebProcess. Add `rel=opener` to the link so that the new window keep opening in the same
+ process, so that `testRunner.windowCount()` actually keeps working as expected.
+ I added an API test to cover to make sure that windows opened by DOM can still close themselves
+ in the case where we swap processes.
+
2021-10-21 Ayumi Kojima <[email protected]>
Regression(r284439): [ iPad ] fast/canvas/canvas-createPattern-video-loading.html is failing.
Modified: trunk/LayoutTests/fast/dom/open-and-close-by-DOM.html (284609 => 284610)
--- trunk/LayoutTests/fast/dom/open-and-close-by-DOM.html 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/fast/dom/open-and-close-by-DOM.html 2021-10-21 16:47:49 UTC (rev 284610)
@@ -53,7 +53,7 @@
<br/>
<div id="console" />
<br/>
-<a href="" id="anchorLink" target="_blank">Open new window that will close itself</a>
+<a href="" id="anchorLink" target="_blank" rel="opener">Open new window that will close itself</a>
<br/><br/>
</body>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (284609 => 284610)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,3 +1,15 @@
+2021-10-21 Chris Dumez <[email protected]>
+
+ WebKit should process-swap for initial navigation of a popup if it has no opener
+ https://bugs.webkit.org/show_bug.cgi?id=231990
+ <rdar://84425504>
+
+ Reviewed by Brent Fulgham.
+
+ * web-platform-tests/html/cross-origin-opener-policy/coop-coep-sandbox.https-expected.txt:
+ * web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https-expected.txt:
+ Rebaseline tests due to minor logging differences.
+
2021-10-20 Alex Christensen <[email protected]>
URLParser should reject hosts with C0 control characters or U+007F
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coep-blob-popup.https-expected.txt (284609 => 284610)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coep-blob-popup.https-expected.txt 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coep-blob-popup.https-expected.txt 2021-10-21 16:47:49 UTC (rev 284610)
@@ -2,6 +2,8 @@
CONSOLE MESSAGE: Fetch API cannot load https://127.0.0.1:9443/common/blank.html due to access control checks.
CONSOLE MESSAGE: Cancelled load to https://127.0.0.1:9443/common/blank.html because it violates the resource's Cross-Origin-Resource-Policy response header.
CONSOLE MESSAGE: Fetch API cannot load https://127.0.0.1:9443/common/blank.html due to access control checks.
+CONSOLE MESSAGE: Cancelled load to https://127.0.0.1:9443/common/blank.html because it violates the resource's Cross-Origin-Resource-Policy response header.
+CONSOLE MESSAGE: Fetch API cannot load https://127.0.0.1:9443/common/blank.html due to access control checks.
PASS COOP+COEP blob URL popup: window.open()
PASS COOP+COEP blob URL popup: <a>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-coep-sandbox.https-expected.txt (284609 => 284610)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-coep-sandbox.https-expected.txt 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-coep-sandbox.https-expected.txt 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,5 +1,4 @@
CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
-CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
PASS <iframe sandbox="allow-popups allow-scripts allow-same-origin"> Sandboxed Cross-Origin-Opener-Policy popup should result in a network error
PASS <iframe sandbox="allow-popups allow-scripts"> Sandboxed Cross-Origin-Opener-Policy popup should result in a network error
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-csp-sandbox.https-expected.txt (284609 => 284610)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-csp-sandbox.https-expected.txt 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-csp-sandbox.https-expected.txt 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,3 +1,5 @@
+CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
+CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
PASS CSP: sandbox allow-popups allow-scripts allow-same-origin; CSP sandboxed Cross-Origin-Opener-Policy popup should result in a network error
PASS CSP: sandbox allow-popups allow-scripts; CSP sandboxed Cross-Origin-Opener-Policy popup should result in a network error
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https-expected.txt (284609 => 284610)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https-expected.txt 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-sandbox.https-expected.txt 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,5 +1,4 @@
CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
-CONSOLE MESSAGE: Navigation was blocked by Cross-Origin-Opener-Policy
PASS <iframe sandbox="allow-popups allow-scripts allow-same-origin"> Sandboxed Cross-Origin-Opener-Policy popup should result in a network error
PASS <iframe sandbox="allow-popups allow-scripts"> Sandboxed Cross-Origin-Opener-Policy popup should result in a network error
Modified: trunk/Source/WebCore/page/Page.h (284609 => 284610)
--- trunk/Source/WebCore/page/Page.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebCore/page/Page.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -279,7 +279,7 @@
const Frame& mainFrame() const { return m_mainFrame.get(); }
bool openedByDOM() const;
- void setOpenedByDOM();
+ WEBCORE_EXPORT void setOpenedByDOM();
bool openedByDOMWithOpener() const { return m_openedByDOMWithOpener; }
void setOpenedByDOMWithOpener(bool value) { m_openedByDOMWithOpener = value; }
Modified: trunk/Source/WebKit/ChangeLog (284609 => 284610)
--- trunk/Source/WebKit/ChangeLog 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/ChangeLog 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,3 +1,55 @@
+2021-10-21 Chris Dumez <[email protected]>
+
+ WebKit should process-swap for initial navigation of a popup if it has no opener
+ https://bugs.webkit.org/show_bug.cgi?id=231990
+ <rdar://84425504>
+
+ Reviewed by Brent Fulgham.
+
+ WebKit should process-swap for initial navigation of a popup if it has no opener, even if the navigation is
+ same-site. Swapping process is not Web-observable here since there is no opener relationship. However, swapping
+ processes has benefits here since we don't want to end up with too many tabs sharing the same process.
+
+ This impacts Google Drive where double-clicking a document will open Google Docs in a new tab and in the same
+ WebProcess as Google Drive.
+
+ No new tests, updated existing API tests and this is not Web-observable.
+
+ * Shared/FrameInfoData.cpp:
+ (WebKit::FrameInfoData::encode const):
+ (WebKit::FrameInfoData::decode):
+ * Shared/FrameInfoData.h:
+ * Shared/LoadParameters.cpp:
+ (WebKit::LoadParameters::encode const):
+ (WebKit::LoadParameters::decode):
+ * Shared/LoadParameters.h:
+ * Shared/NavigationActionData.cpp:
+ (WebKit::NavigationActionData::encode const):
+ (WebKit::NavigationActionData::decode):
+ * Shared/NavigationActionData.h:
+ * UIProcess/API/APINavigation.h:
+ (API::Navigation::effectiveSandboxFlags const):
+ * UIProcess/Cocoa/UIDelegate.mm:
+ (WebKit::UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest):
+ * UIProcess/ProvisionalPageProxy.cpp:
+ (WebKit::ProvisionalPageProxy::cancel):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::loadRequestWithNavigationShared):
+ (WebKit::WebPageProxy::loadSimulatedRequest):
+ (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::processForNavigation):
+ (WebKit::WebProcessPool::processForNavigationInternal):
+ * UIProcess/WebProcessPool.h:
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+ * WebProcess/WebPage/WebFrame.cpp:
+ (WebKit::WebFrame::info const):
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::loadRequest):
+
2021-10-21 Chris Lord <[email protected]>
[WPE][GTK] Enable smooth scrolling by default
Modified: trunk/Source/WebKit/Shared/FrameInfoData.cpp (284609 => 284610)
--- trunk/Source/WebKit/Shared/FrameInfoData.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/FrameInfoData.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -35,6 +35,7 @@
encoder << isMainFrame;
encoder << request;
encoder << securityOrigin;
+ encoder << frameName;
encoder << frameID;
encoder << parentFrameID;
}
@@ -56,6 +57,11 @@
if (!securityOrigin)
return std::nullopt;
+ std::optional<String> frameName;
+ decoder >> frameName;
+ if (!frameName)
+ return std::nullopt;
+
std::optional<std::optional<WebCore::FrameIdentifier>> frameID;
decoder >> frameID;
if (!frameID)
@@ -70,6 +76,7 @@
WTFMove(*isMainFrame),
WTFMove(*request),
WTFMove(*securityOrigin),
+ WTFMove(*frameName),
WTFMove(*frameID),
WTFMove(*parentFrameID)
}};
Modified: trunk/Source/WebKit/Shared/FrameInfoData.h (284609 => 284610)
--- trunk/Source/WebKit/Shared/FrameInfoData.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/FrameInfoData.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -43,6 +43,7 @@
bool isMainFrame { false };
WebCore::ResourceRequest request;
WebCore::SecurityOriginData securityOrigin;
+ String frameName;
std::optional<WebCore::FrameIdentifier> frameID;
std::optional<WebCore::FrameIdentifier> parentFrameID;
};
Modified: trunk/Source/WebKit/Shared/LoadParameters.cpp (284609 => 284610)
--- trunk/Source/WebKit/Shared/LoadParameters.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/LoadParameters.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -56,6 +56,7 @@
encoder << lockHistory;
encoder << lockBackForwardList;
encoder << clientRedirectSourceForHistory;
+ encoder << effectiveSandboxFlags;
encoder << isNavigatingToAppBoundDomain;
encoder << existingNetworkResourceLoadIdentifierToResume;
encoder << isServiceWorkerLoad;
@@ -136,6 +137,12 @@
if (!clientRedirectSourceForHistory)
return false;
data.clientRedirectSourceForHistory = WTFMove(*clientRedirectSourceForHistory);
+
+ std::optional<WebCore::SandboxFlags> effectiveSandboxFlags;
+ decoder >> effectiveSandboxFlags;
+ if (!effectiveSandboxFlags)
+ return false;
+ data.effectiveSandboxFlags = *effectiveSandboxFlags;
if (!decoder.decode(data.isNavigatingToAppBoundDomain))
return false;
Modified: trunk/Source/WebKit/Shared/LoadParameters.h (284609 => 284610)
--- trunk/Source/WebKit/Shared/LoadParameters.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/LoadParameters.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -43,6 +43,10 @@
class Encoder;
}
+namespace WebCore {
+typedef int SandboxFlags;
+}
+
namespace WebKit {
struct LoadParameters {
@@ -74,6 +78,7 @@
WebCore::LockBackForwardList lockBackForwardList { WebCore::LockBackForwardList::No };
WebCore::SubstituteData::SessionHistoryVisibility sessionHistoryVisibility { WebCore::SubstituteData::SessionHistoryVisibility::Visible };
String clientRedirectSourceForHistory;
+ WebCore::SandboxFlags effectiveSandboxFlags { 0 };
std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain;
std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume;
bool isServiceWorkerLoad { false };
Modified: trunk/Source/WebKit/Shared/NavigationActionData.cpp (284609 => 284610)
--- trunk/Source/WebKit/Shared/NavigationActionData.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/NavigationActionData.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -54,6 +54,7 @@
encoder << lockHistory;
encoder << lockBackForwardList;
encoder << clientRedirectSourceForHistory;
+ encoder << effectiveSandboxFlags;
encoder << privateClickMeasurement;
}
@@ -146,6 +147,11 @@
if (!clientRedirectSourceForHistory)
return std::nullopt;
+ std::optional<WebCore::SandboxFlags> effectiveSandboxFlags;
+ decoder >> effectiveSandboxFlags;
+ if (!effectiveSandboxFlags)
+ return std::nullopt;
+
std::optional<std::optional<WebCore::PrivateClickMeasurement>> privateClickMeasurement;
decoder >> privateClickMeasurement;
if (!privateClickMeasurement)
@@ -154,7 +160,7 @@
return {{ WTFMove(navigationType), modifiers, WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier),
WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates),
WTFMove(*isRedirect), *treatAsSameOriginNavigation, *hasOpenedFrames, *openedByDOMWithOpener, WTFMove(*requesterOrigin),
- WTFMove(*targetBackForwardItemIdentifier), WTFMove(*sourceBackForwardItemIdentifier), lockHistory, lockBackForwardList, WTFMove(*clientRedirectSourceForHistory), WTFMove(*privateClickMeasurement) }};
+ WTFMove(*targetBackForwardItemIdentifier), WTFMove(*sourceBackForwardItemIdentifier), lockHistory, lockBackForwardList, WTFMove(*clientRedirectSourceForHistory), *effectiveSandboxFlags, WTFMove(*privateClickMeasurement) }};
}
} // namespace WebKit
Modified: trunk/Source/WebKit/Shared/NavigationActionData.h (284609 => 284610)
--- trunk/Source/WebKit/Shared/NavigationActionData.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/NavigationActionData.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -37,6 +37,10 @@
class Encoder;
}
+namespace WebCore {
+typedef int SandboxFlags;
+}
+
namespace WebKit {
struct NavigationActionData {
@@ -62,6 +66,7 @@
WebCore::LockHistory lockHistory { WebCore::LockHistory::No };
WebCore::LockBackForwardList lockBackForwardList { WebCore::LockBackForwardList::No };
WTF::String clientRedirectSourceForHistory;
+ WebCore::SandboxFlags effectiveSandboxFlags { 0 };
std::optional<WebCore::PrivateClickMeasurement> privateClickMeasurement;
};
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp (284609 => 284610)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -65,6 +65,7 @@
encoder << topContentInset;
encoder << mediaVolume;
encoder << muted;
+ encoder << openedByDOM;
encoder << mayStartMediaWhenInWindow;
encoder << mediaPlaybackIsSuspended;
encoder << minimumSizeForAutoLayout;
@@ -290,6 +291,8 @@
return std::nullopt;
parameters.muted = *mutedStateFlags;
+ if (!decoder.decode(parameters.openedByDOM))
+ return std::nullopt;
if (!decoder.decode(parameters.mayStartMediaWhenInWindow))
return std::nullopt;
if (!decoder.decode(parameters.mediaPlaybackIsSuspended))
Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.h (284609 => 284610)
--- trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -120,6 +120,7 @@
float mediaVolume;
WebCore::MediaProducerMutedStateFlags muted;
+ bool openedByDOM { false };
bool mayStartMediaWhenInWindow;
bool mediaPlaybackIsSuspended { false };
Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/API/APINavigation.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -144,6 +144,7 @@
WebCore::LockBackForwardList lockBackForwardList() const { return m_lastNavigationAction.lockBackForwardList; }
WTF::String clientRedirectSourceForHistory() const { return m_lastNavigationAction.clientRedirectSourceForHistory; }
+ WebCore::SandboxFlags effectiveSandboxFlags() const { return m_lastNavigationAction.effectiveSandboxFlags; }
void setLastNavigationAction(const WebKit::NavigationActionData& navigationAction) { m_lastNavigationAction = navigationAction; }
const WebKit::NavigationActionData& lastNavigationAction() const { return m_lastNavigationAction; }
Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1152,7 +1152,7 @@
std::optional<WebCore::FrameIdentifier> mainFrameID;
if (auto* mainFrame = frame.page() ? frame.page()->mainFrame() : nullptr)
mainFrameID = mainFrame->frameID();
- FrameInfoData frameInfo { frame.isMainFrame(), { }, userMediaOrigin.securityOrigin(), frame.frameID(), mainFrameID };
+ FrameInfoData frameInfo { frame.isMainFrame(), { }, userMediaOrigin.securityOrigin(), { }, frame.frameID(), mainFrameID };
RetainPtr<WKFrameInfo> frameInfoWrapper = wrapper(API::FrameInfo::create(WTFMove(frameInfo), frame.page()));
WKMediaCaptureType type = WKMediaCaptureTypeCamera;
Modified: trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -149,6 +149,7 @@
true, // isMainFrame
m_request,
SecurityOriginData::fromURL(m_request.url()),
+ { },
m_mainFrame->frameID(),
std::nullopt,
};
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1416,6 +1416,7 @@
loadParameters.lockHistory = navigation.lockHistory();
loadParameters.lockBackForwardList = navigation.lockBackForwardList();
loadParameters.clientRedirectSourceForHistory = navigation.clientRedirectSourceForHistory();
+ loadParameters.effectiveSandboxFlags = navigation.effectiveSandboxFlags();
loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
loadParameters.existingNetworkResourceLoadIdentifierToResume = existingNetworkResourceLoadIdentifierToResume;
maybeInitializeSandboxExtensionHandle(process, url, m_pageLoadState.resourceDirectoryURL(), loadParameters.sandboxExtensionHandle);
@@ -1602,6 +1603,7 @@
loadParameters.lockHistory = navigation->lockHistory();
loadParameters.lockBackForwardList = navigation->lockBackForwardList();
loadParameters.clientRedirectSourceForHistory = navigation->clientRedirectSourceForHistory();
+ loadParameters.effectiveSandboxFlags = navigation->effectiveSandboxFlags();
loadParameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain();
simulatedResponse.setExpectedContentLength(data.size());
@@ -3455,7 +3457,7 @@
#endif
}
-void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, RefPtr<API::WebsitePolicies>&& policies, Ref<PolicyDecisionSender>&& sender)
+void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, const FrameInfoData& frameInfo, RefPtr<API::WebsitePolicies>&& policies, Ref<PolicyDecisionSender>&& sender)
{
WEBPAGEPROXY_RELEASE_LOG(Loading, "receivedNavigationPolicyDecision: frameID=%llu, navigationID=%llu, policyAction=%u", frame.frameID().toUInt64(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction);
@@ -3508,7 +3510,7 @@
}
}
- process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(),
+ process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, frameInfo, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(),
policies = WTFMove(policies), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
// If the navigation has been destroyed, then no need to proceed.
if (isClosed() || !navigationState().hasNavigation(navigation->navigationID())) {
@@ -5430,7 +5432,7 @@
Ref listener = frame.setUpPolicyListenerProxy([this, protectedThis = Ref { *this }, frame = Ref { frame }, sender = WTFMove(sender), navigation, navigationAction, frameInfo, userDataObject = process->transformHandlesToObjects(userData.object()).get()] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, std::optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
WEBPAGEPROXY_RELEASE_LOG(Loading, "decidePolicyForNavigationAction: listener called: frameID=%llu, navigationID=%llu, policyAction=%u, safeBrowsingWarning=%d, isAppBoundDomain=%d", frame->frameID().toUInt64(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction, !!safeBrowsingWarning, !!isAppBoundDomain);
- auto completionHandler = [this, protectedThis, frame, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient, policies = RefPtr { policies }] (PolicyAction policyAction) mutable {
+ auto completionHandler = [this, protectedThis, frame, frameInfo, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient, policies = RefPtr { policies }] (PolicyAction policyAction) mutable {
if (frame->isMainFrame()) {
if (!policies) {
if (auto* defaultPolicies = m_configuration->defaultWebsitePolicies())
@@ -5439,7 +5441,7 @@
if (policies)
navigation->setEffectiveContentMode(effectiveContentModeAfterAdjustingPolicies(*policies, navigation->currentRequest()));
}
- receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, WTFMove(policies), WTFMove(sender));
+ receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, frameInfo, WTFMove(policies), WTFMove(sender));
};
#if ENABLE(APP_BOUND_DOMAINS)
@@ -8221,6 +8223,7 @@
parameters.topContentInset = m_topContentInset;
parameters.mediaVolume = m_mediaVolume;
parameters.muted = m_mutedState;
+ parameters.openedByDOM = m_openedByDOM;
parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow;
parameters.mediaPlaybackIsSuspended = m_mediaPlaybackIsSuspended;
parameters.minimumSizeForAutoLayout = m_minimumSizeForAutoLayout;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1223,7 +1223,7 @@
class PolicyDecisionSender;
enum class WillContinueLoadInNewProcess : bool { No, Yes };
void receivedPolicyDecision(WebCore::PolicyAction, API::Navigation*, RefPtr<API::WebsitePolicies>&&, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&&, Ref<PolicyDecisionSender>&&, std::optional<SandboxExtension::Handle> = { }, WillContinueLoadInNewProcess = WillContinueLoadInNewProcess::No);
- void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, RefPtr<API::WebsitePolicies>&&, Ref<PolicyDecisionSender>&&);
+ void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, const FrameInfoData&, RefPtr<API::WebsitePolicies>&&, Ref<PolicyDecisionSender>&&);
void backForwardRemovedItem(const WebCore::BackForwardItemIdentifier&);
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1814,9 +1814,9 @@
m_swappedProcessesPerRegistrableDomain.remove(registrableDomain);
}
-void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
+void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
{
- processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, WTFMove(dataStore), [this, page = Ref { page }, navigation = Ref { navigation }, sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
+ processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, frameInfo, WTFMove(dataStore), [this, page = Ref { page }, navigation = Ref { navigation }, sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
// We are process-swapping so automatic process prewarming would be beneficial if the client has not explicitly enabled / disabled it.
bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != sourceProcess.ptr();
if (doingAnAutomaticProcessSwap && !configuration().wasAutomaticProcessWarmingSetByClient() && !configuration().clientWouldBenefitFromAutomaticProcessPrewarming()) {
@@ -1839,7 +1839,7 @@
});
}
-void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
+void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
{
auto& targetURL = navigation.currentRequest().url();
auto targetRegistrableDomain = WebCore::RegistrableDomain { targetURL };
@@ -1897,6 +1897,13 @@
}
}
+ // If it is the first navigation in a DOM popup and there is no opener, then force a process swap no matter what since
+ // popup windows are originally created in their opener's process.
+ // Note that we currently do not process swap if the window popup has a name. In theory, we should be able to swap in this case too
+ // but we would need to transfer over the name to the new process. At this point, it is not clear it is worth the extra complexity.
+ if (page.openedByDOM() && !navigation.openedByDOMWithOpener() && !page.hasCommittedAnyProvisionalLoads() && frameInfo.frameName.isEmpty() && !targetURL.protocolIsBlob())
+ return completionHandler(createNewProcess(), nullptr, "Process swap because this is a first navigation in a DOM popup without opener"_s);
+
if (navigation.treatAsSameOriginNavigation())
return completionHandler(WTFMove(sourceProcess), nullptr, "The treatAsSameOriginNavigation flag is set"_s);
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (284609 => 284610)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -446,7 +446,7 @@
bool hasForegroundWebProcesses() const { return m_foregroundWebProcessCounter.value(); }
bool hasBackgroundWebProcesses() const { return m_backgroundWebProcessCounter.value(); }
- void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
+ void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
void didReachGoodTimeToPrewarm();
@@ -523,7 +523,7 @@
void platformInitializeWebProcess(const WebProcessProxy&, WebProcessCreationParameters&);
void platformInvalidateContext();
- void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
+ void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (284609 => 284610)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -968,6 +968,7 @@
navigationAction.initiatedByMainFrame() == InitiatedByMainFrame::Yes,
ResourceRequest { requester.url },
requester.securityOrigin->data(),
+ { },
WTFMove(originatingFrameID),
WTFMove(parentFrameID),
};
@@ -1012,6 +1013,7 @@
documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
navigationActionData.clientRedirectSourceForHistory = documentLoader->clientRedirectSourceForHistory();
+ navigationActionData.effectiveSandboxFlags = coreFrame->loader().effectiveSandboxFlags();
// Notify the UIProcess.
Ref protector { *coreFrame };
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp (284609 => 284610)
--- trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -193,6 +193,7 @@
// FIXME: This should use the full request.
ResourceRequest(url()),
SecurityOriginData::fromFrame(m_coreFrame.get()),
+ m_coreFrame ? m_coreFrame->tree().name().string() : String(),
m_frameID,
parent ? std::optional<WebCore::FrameIdentifier> { parent->frameID() } : std::nullopt,
};
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (284609 => 284610)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -726,6 +726,9 @@
if (parameters.mediaPlaybackIsSuspended)
m_page->suspendAllMediaPlayback();
+ if (parameters.openedByDOM)
+ m_page->setOpenedByDOM();
+
m_page->setGroupName(m_pageGroup->identifier());
m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
m_page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection);
@@ -1733,6 +1736,9 @@
frameLoadRequest.setClientRedirectSourceForHistory(loadParameters.clientRedirectSourceForHistory);
frameLoadRequest.setIsRequestFromClientOrUserInput();
+ if (loadParameters.effectiveSandboxFlags)
+ corePage()->mainFrame().loader().forceSandboxFlags(loadParameters.effectiveSandboxFlags);
+
corePage()->userInputBridge().loadRequest(WTFMove(frameLoadRequest));
ASSERT(!m_pendingNavigationID);
Modified: trunk/Tools/ChangeLog (284609 => 284610)
--- trunk/Tools/ChangeLog 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/ChangeLog 2021-10-21 16:47:49 UTC (rev 284610)
@@ -1,3 +1,38 @@
+2021-10-21 Chris Dumez <[email protected]>
+
+ WebKit should process-swap for initial navigation of a popup if it has no opener
+ https://bugs.webkit.org/show_bug.cgi?id=231990
+ <rdar://84425504>
+
+ Reviewed by Brent Fulgham.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+ (-[PSONUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
+ (-[PSONUIDelegate webViewDidClose:]):
+ Updated existing API tests to reflect behavior change.
+ Also extend an API test to make sure that a popup opened by JS can still close itself
+ via JS (by calling window.close()), even in the case where we process swap.
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+ (WTR::InjectedBundle::didReceiveMessageToPage):
+ (WTR::InjectedBundle::outputText):
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.h:
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::dump):
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::createOtherPage):
+ (WTR::TestController::didReceivePageMessageFromInjectedBundle):
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+ We have some tests that open a new popup with 'noopener' and the popup would be the
+ one to call `testRunner.notifyDone()`. This used to work fine when the popup would
+ end up in the same WebProcess because the injected bundle would know which page is
+ the main test page and use that one. However, now that we process-swap, the popup
+ page would think it is the main test page and try to dump its own output. However,
+ the UIProcess wasn't listening for messages from auxiliary pages' injected bundles.
+ The UIProcess now listens for those messages and asks the main test page to dump
+ its output when an auxiliary page in another process says the test is done.
+
2021-10-21 Simon Fraser <[email protected]>
run-webkit-tests --ios-simulator --print-expectations fails
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (284609 => 284610)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2021-10-21 16:47:49 UTC (rev 284610)
@@ -86,6 +86,7 @@
static bool willPerformClientRedirect;
static bool didPerformClientRedirect;
static bool shouldConvertToDownload;
+static bool didCloseWindow;
static RetainPtr<NSURL> clientRedirectSourceURL;
static RetainPtr<NSURL> clientRedirectDestinationURL;
@@ -241,10 +242,18 @@
{
createdWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
[createdWebView setNavigationDelegate:_navigationDelegate.get()];
+ [createdWebView setUIDelegate:self];
didCreateWebView = true;
return createdWebView.get();
}
+- (void)webViewDidClose:(WKWebView *)webView
+{
+ EXPECT_EQ(createdWebView.get(), webView);
+ createdWebView = nullptr;
+ didCloseWindow = true;
+}
+
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
{
didReceiveAlert = true;
@@ -456,11 +465,20 @@
<script>
window._onload_ = function() {
if (!opener)
- window.open("pson://www.webkit.org/main.html", "_blank", "noopener");
+ window.open("pson://www.webkit.org/popup.html", "_blank", "noopener");
}
</script>
)PSONRESOURCE";
+static const char* windowOpenWithNameSameSiteNoOpenerTestBytes = R"PSONRESOURCE(
+<script>
+window._onload_ = function() {
+ if (!opener)
+ window.open("pson://www.webkit.org/popup.html", "foo", "noopener");
+}
+</script>
+)PSONRESOURCE";
+
static const char* targetBlankCrossSiteWithExplicitOpenerTestBytes = R"PSONRESOURCE(
<a id="testLink" target="_blank" href="" rel="opener">Link</a>
<script>
@@ -1283,7 +1301,8 @@
auto pid2 = [createdWebView _webProcessIdentifier];
EXPECT_TRUE(!!pid2);
- EXPECT_EQ(pid1, pid2);
+ // Since there is no opener, we process-swap, even though the navigation is same-site.
+ EXPECT_NE(pid1, pid2);
}
TEST(ProcessSwap, CrossSiteWindowOpenWithOpener)
@@ -1327,7 +1346,9 @@
EXPECT_NE(pid1, pid2);
}
-TEST(ProcessSwap, SameSiteWindowOpenNoOpener)
+enum class ExpectSwap { No, Yes };
+enum class WindowHasName : bool { No, Yes };
+static void runSameSiteWindowOpenNoOpenerTest(WindowHasName windowHasName, ExpectSwap expectSwap)
{
auto processPoolConfiguration = psonProcessPoolConfiguration();
auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
@@ -1335,7 +1356,11 @@
auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
[webViewConfiguration setProcessPool:processPool.get()];
[webViewConfiguration preferences]._javascript_CanOpenWindowsAutomatically = YES;
- auto handler = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenSameSiteNoOpenerTestBytes]);
+ auto handler = adoptNS([[PSONScheme alloc] init]);
+ if (windowHasName == WindowHasName::Yes)
+ [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenWithNameSameSiteNoOpenerTestBytes];
+ else
+ [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:windowOpenSameSiteNoOpenerTestBytes];
[webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
@@ -1363,9 +1388,39 @@
auto pid2 = [createdWebView _webProcessIdentifier];
EXPECT_TRUE(!!pid2);
- EXPECT_EQ(pid1, pid2);
+ // Since there is no opener, we process-swap, even though the navigation is same-site.
+ if (expectSwap == ExpectSwap::Yes)
+ EXPECT_NE(pid1, pid2);
+ else
+ EXPECT_EQ(pid1, pid2);
+
+ done = false;
+ request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/popup2.html"]];
+ [createdWebView loadRequest:request];
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+ EXPECT_EQ(pid2, [createdWebView _webProcessIdentifier]);
+
+ // Since the window was opened via JS, it should be able to close itself.
+ didCloseWindow = false;
+ [createdWebView evaluateJavaScript:@"window.close()" completionHandler:nil];
+ TestWebKitAPI::Util::run(&didCloseWindow);
}
+TEST(ProcessSwap, SameSiteWindowOpenNoOpener)
+{
+ // We process-swap even though the navigation is same-site, because the popup has no opener.
+ runSameSiteWindowOpenNoOpenerTest(WindowHasName::No, ExpectSwap::Yes);
+}
+
+TEST(ProcessSwap, SameSiteWindowOpenWithNameNoOpener)
+{
+ // We currently do no process-swap when navigating same-site a popup without opener if the window
+ // has a name. We should be able to support this but we would need to pass the window name over
+ // to the new process.
+ runSameSiteWindowOpenNoOpenerTest(WindowHasName::Yes, ExpectSwap::No);
+}
+
TEST(ProcessSwap, CrossSiteBlankTargetWithOpener)
{
auto processPoolConfiguration = psonProcessPoolConfiguration();
@@ -1523,7 +1578,8 @@
auto pid2 = [createdWebView _webProcessIdentifier];
EXPECT_TRUE(!!pid2);
- EXPECT_EQ(pid1, pid2);
+ // Since there is no opener, we process-swap, even though the navigation is same-site.
+ EXPECT_NE(pid1, pid2);
}
TEST(ProcessSwap, ServerRedirectFromNewWebView)
@@ -5253,7 +5309,6 @@
done = false;
}
-enum class ExpectSwap { No, Yes };
static void runProcessSwapDueToRelatedWebViewTest(NSURL* relatedViewURL, NSURL* targetURL, ExpectSwap expectSwap)
{
auto processPoolConfiguration = psonProcessPoolConfiguration();
@@ -6269,8 +6324,10 @@
// New WKWebView has now navigated to webkit.org.
EXPECT_WK_STREQ(@"pson://www.webkit.org/main2.html", [[createdWebView URL] absoluteString]);
auto pid2 = [createdWebView _webProcessIdentifier];
- EXPECT_EQ(pid1, pid2);
+ // We process-swap since there is no opener relationship.
+ EXPECT_NE(pid1, pid2);
+
// Click link in new WKWebView so that it navigates cross-site to apple.com.
[createdWebView evaluateJavaScript:@"testLink.click()" completionHandler:nil];
TestWebKitAPI::Util::run(&done);
@@ -6288,7 +6345,7 @@
EXPECT_WK_STREQ(@"pson://www.webkit.org/main2.html", [[createdWebView URL] absoluteString]);
auto pid4 = [createdWebView _webProcessIdentifier];
- EXPECT_EQ(pid1, pid4); // Should have process-swapped to the original "suspended" process.
+ EXPECT_EQ(pid2, pid4); // Should have process-swapped to the original "suspended" process.
// Do a fragment navigation in the original WKWebView and make sure this does not crash.
request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main1.html#testLink"]];
@@ -6298,7 +6355,7 @@
EXPECT_WK_STREQ(@"pson://www.webkit.org/main1.html#testLink", [[webView1 URL] absoluteString]);
auto pid5 = [createdWebView _webProcessIdentifier];
- EXPECT_EQ(pid1, pid5);
+ EXPECT_EQ(pid2, pid5);
}
#endif // PLATFORM(MAC)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (284609 => 284610)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -437,6 +437,11 @@
return;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "NotifyDone")) {
+ InjectedBundle::page()->dump();
+ return;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
auto messageBodyDictionary = dictionaryValue(messageBody);
auto callbackID = uint64Value(messageBodyDictionary, "CallbackID");
@@ -589,7 +594,7 @@
postPageMessage("DumpToStdErr", string ? string->data() : "Out of memory\n");
}
-void InjectedBundle::outputText(const String& output)
+void InjectedBundle::outputText(const String& output, IsFinalTestOutput isFinalTestOutput)
{
if (m_state != Testing)
return;
@@ -600,7 +605,8 @@
// We use WKBundlePagePostMessageIgnoringFullySynchronousMode() instead of WKBundlePagePostMessage() to make sure that all text output
// is done via asynchronous IPC, even if the connection is in fully synchronous mode due to a WKBundlePagePostSynchronousMessageForTesting()
// call. Otherwise, messages logged via sync and async IPC may end up out of order and cause flakiness.
- WKBundlePagePostMessageIgnoringFullySynchronousMode(page()->page(), toWK("TextOutput").get(), toWK(string ? string->data() : "Out of memory\n").get());
+ auto messageName = isFinalTestOutput == IsFinalTestOutput::Yes ? toWK("FinalTextOutput") : toWK("TextOutput");
+ WKBundlePagePostMessageIgnoringFullySynchronousMode(page()->page(), messageName.get(), toWK(string ? string->data() : "Out of memory\n").get());
}
void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h (284609 => 284610)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h 2021-10-21 16:47:49 UTC (rev 284610)
@@ -81,7 +81,8 @@
bool shouldDumpPixels() const { return m_dumpPixels; }
bool dumpJSConsoleLogInStdErr() const { return m_dumpJSConsoleLogInStdErr; };
- void outputText(const String&);
+ enum class IsFinalTestOutput : bool { No, Yes };
+ void outputText(const String&, IsFinalTestOutput = IsFinalTestOutput::No);
void dumpToStdErr(const String&);
void postNewBeforeUnloadReturnValue(bool);
void postAddChromeInputField();
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (284609 => 284610)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -846,7 +846,7 @@
injectedBundle.setRepaintRects(adoptWK(WKBundlePageCopyTrackedRepaintRects(m_page)).get());
}
- injectedBundle.outputText(stringBuilder.toString());
+ injectedBundle.outputText(stringBuilder.toString(), InjectedBundle::IsFinalTestOutput::Yes);
injectedBundle.done();
}
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (284609 => 284610)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -491,6 +491,14 @@
};
WKPageSetPageNavigationClient(newPage, &pageNavigationClient.base);
+ WKPageInjectedBundleClientV1 injectedBundleClient = {
+ { 1, this },
+ didReceivePageMessageFromInjectedBundle,
+ nullptr,
+ didReceiveSynchronousPageMessageFromInjectedBundleWithListener,
+ };
+ WKPageSetPageInjectedBundleClient(newPage, &injectedBundleClient.base);
+
view->didInitializeClients();
TestController::singleton().updateWindowScaleForTest(view.ptr(), *TestController::singleton().m_currentInvocation);
@@ -1572,7 +1580,16 @@
void TestController::didReceivePageMessageFromInjectedBundle(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
{
- static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveMessageFromInjectedBundle(messageName, messageBody);
+ auto* testController = static_cast<TestController*>(const_cast<void*>(clientInfo));
+ if (page != testController->mainWebView()->page()) {
+ // If this is a Done message from an auxiliary view in its own WebProcess (due to process-swapping), we need to notify the injected bundle of the main WebView
+ // that the test is done.
+ if (WKStringIsEqualToUTF8CString(messageName, "Done") && testController->m_currentInvocation)
+ WKPagePostMessageToInjectedBundle(testController->mainWebView()->page(), toWK("NotifyDone").get(), nullptr);
+ if (!WKStringIsEqualToUTF8CString(messageName, "TextOutput"))
+ return;
+ }
+ testController->didReceiveMessageFromInjectedBundle(messageName, messageBody);
}
void TestController::didReceiveSynchronousPageMessageFromInjectedBundleWithListener(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, WKMessageListenerRef listener, const void* clientInfo)
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (284609 => 284610)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2021-10-21 16:34:16 UTC (rev 284609)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2021-10-21 16:47:49 UTC (rev 284610)
@@ -332,7 +332,7 @@
return;
}
- if (WKStringIsEqualToUTF8CString(messageName, "TextOutput")) {
+ if (WKStringIsEqualToUTF8CString(messageName, "TextOutput") || WKStringIsEqualToUTF8CString(messageName, "FinalTextOutput")) {
m_textOutput.append(toWTFString(stringValue(messageBody)));
return;
}