Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 146e2d55606c4b52a17fddf992bf98e556b6e3e9
https://github.com/WebKit/WebKit/commit/146e2d55606c4b52a17fddf992bf98e556b6e3e9
Author: Basuke Suzuki <[email protected]>
Date: 2026-07-07 (Tue, 07 Jul 2026)
Changed paths:
M Source/WebKit/Shared/WebBackForwardListItem.cpp
M Source/WebKit/Shared/WebBackForwardListItem.h
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
Log Message:
-----------
[Site Isolation] Main-frame Back is a no-op after a cross-site iframe created
a back/forward entry
https://bugs.webkit.org/show_bug.cgi?id=318488
rdar://181175045
Reviewed by Sihui Liu.
Under Site Isolation, after a cross-site iframe creates a back/forward entry
(e.g. by
submitting a GET form so the iframe navigates) and the main frame then
navigates away,
pressing Back was a no-op: the main frame never traversed and the screen did
not change.
With Site Isolation off the identical sequence works, so the bug was
SI-specific.
Root cause: a cross-site child-frame navigation stacks a new joint back/forward
item
(created by the iframe's process) that describes the same main-frame document
as the item
the main frame's process still knows as current. When the main frame later
navigates away,
the WebProcess caches the outgoing main-frame document and reports
DidCacheBackForwardItem
keyed to its own -- now stale -- main-frame item.
WebPageProxy::didCacheBackForwardItem
therefore attached the back/forward cache entry to the stale item, not to the
current joint
item that a subsequent main-frame Back actually targets. On goBack,
WebPageProxy::goToBackForwardItem found no cache entry on the target item, set
ShouldRestoreFromBackForwardCache to No, and the WebProcess evicted its own
valid cached
page instead of restoring it -- so the main frame never committed and Back was
a no-op.
Fix: in didCacheBackForwardItem, when the reported item is not the current item
but the two
have the same main-frame history entry, attach the cache entry to the current
item so it
lands on the item Back will actually traverse. The new
WebBackForwardListItem::hasSameMainFrameHistoryEntry compares the two main
frames' item and
document sequence numbers only -- unlike itemIsClone(), it ignores subframe
differences,
which is what distinguishes the stale item from the joint item that carries the
iframe entry.
This relies on DidCacheBackForwardItem (sent from the outgoing page's
FrameLoader::commitProvisionalLoad) being delivered before BackForwardAddItem
for the
incoming main-frame item, so currentItem() is still the joint item here. That
holds for a
same-process main-frame navigation because both IPCs ride one connection; a
cross-site (PSON)
outgoing page is suspended via SuspendedPageProxy and never reaches this
in-process cache path.
Tested by a new API test,
SiteIsolation.CrossSiteIframeBackForwardEntryThenMainFrameBackTraverses:
it is a no-op Back (fails) without this change and traverses correctly with it.
The paired
CrossSiteIframeBackForwardEntryThenMainFrameBackTraversesWithoutSiteIsolation
is the SI-off control.
* Source/WebKit/Shared/WebBackForwardListItem.cpp:
(WebKit::WebBackForwardListItem::hasSameMainFrameHistoryEntry):
* Source/WebKit/Shared/WebBackForwardListItem.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didCacheBackForwardItem):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(testCrossSiteIframeBackForwardEntryThenMainFrameBack):
(TestWebKitAPI::TEST):
Canonical link: https://commits.webkit.org/316688@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications