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

Reply via email to