Skip to content

Commit

Permalink
[Site Isolation] Session restore in a new WKWebView breaks when resto…
Browse files Browse the repository at this point in the history
…ring from an existing WKWebView

https://bugs.webkit.org/show_bug.cgi?id=288162
rdar://145257058

Reviewed by Alex Christensen.

There's logic in WebPageProxy::goToBackForwardItem to send FrameState to the right frame process, but we
didn’t check if the frame actually belonged to the current page. So, after restoring session state from
another WKWebView, we could end up trying to send FrameState to a process belonging to a different page.
We should make sure the frame belongs to the current page before sending IPC to its process.

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::goToBackForwardItem):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/SiteIsolation.mm:
(TestWebKitAPI::TEST(SiteIsolation, RestoreSessionFromAnotherWebView)):

Canonical link: https://commits.webkit.org/290832@main
  • Loading branch information
charliewolfe committed Feb 21, 2025
1 parent 055d5a9 commit 5fb0bc3
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Source/WebKit/UIProcess/WebPageProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2582,7 +2582,7 @@ RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListFram

Ref frameState = item->mainFrameState();
if (protectedPreferences()->siteIsolationEnabled()) {
if (RefPtr frame = WebFrameProxy::webFrame(frameItem.frameID())) {
if (RefPtr frame = WebFrameProxy::webFrame(frameItem.frameID()); frame && frame->page() == this) {
process = frame->process();
frameState = frameItem.copyFrameStateWithChildren();
}
Expand Down
15 changes: 15 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/SiteIsolation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3061,6 +3061,21 @@ HTTPServer server({
EXPECT_TRUE([webView canGoBack]);
}

TEST(SiteIsolation, RestoreSessionFromAnotherWebView)
{
HTTPServer server({
{ "/example"_s, { "<iframe src='https://webkit.org/frame'></iframe>"_s } },
{ "/frame"_s, { "<script> alert('done'); </script>"_s } }
}, HTTPServer::Protocol::HttpsProxy);
auto [webView1, navigationDelegate] = siteIsolatedViewAndDelegate(server);
[webView1 loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/example"]]];
EXPECT_WK_STREQ([webView1 _test_waitForAlert], "done");

auto [webView2, navigationDelegate2] = siteIsolatedViewAndDelegate(server);
[webView2 _restoreSessionState:[webView1 _sessionState] andNavigate:YES];
EXPECT_WK_STREQ([webView2 _test_waitForAlert], "done");
}

static void testNavigateIframeBackForward(NSString *navigationURL, bool restoreSessionState)
{
HTTPServer server({
Expand Down

0 comments on commit 5fb0bc3

Please sign in to comment.