Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 3c248d1e5f942b73d0dc1f9cd46fb3c36e03fe56
      
https://github.com/WebKit/WebKit/commit/3c248d1e5f942b73d0dc1f9cd46fb3c36e03fe56
  Author: Sihui Liu <[email protected]>
  Date:   2026-07-31 (Fri, 31 Jul 2026)

  Changed paths:
    M Source/WebCore/history/BackForwardCache.cpp
    M Source/WebCore/history/BackForwardCache.h
    M Source/WebCore/history/CachedPage.h
    M Source/WebCore/page/Frame.cpp
    M Source/WebKit/WebProcess/WebPage/WebPage.cpp
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm

  Log Message:
  -----------
  [Site Isolation] Cross-site iframe does not render after same-site top-level 
navigation
https://bugs.webkit.org/show_bug.cgi?id=320633
rdar://182905055

Reviewed by Alex Christensen.

The subscribe widget iframe on bbc.com's /subscribe page (piano.io) never 
loaded when reached by clicking a same-site
link from bbc.com's home page, even though it worked fine when /subscribe was 
loaded directly.

The cause is that same-site top-level navigation (no process swap for the main 
frame, e.g. bbc.com -> bbc.com/subscribe)
can reuse the same WebPage/process for a cross-site iframe present on both the 
old and new page. Caching the old page
into BackForwardCache broadcasts SuspendWithFrameItem to that shared iframe 
process, and the previous code responded by
calling freezeLayerTree() on the whole WebPage. Since the new page's own iframe 
is added to that same, now-frozen
WebPage moments later, it inherited the freeze before ever rendering a single 
frame and stayed permanently blank.

Fixed by having suspendWithFrameItem only detach the specific root frame(s) 
being cached from Page::rootFrames() -- pure
compositing bookkeeping; the frame stays alive via its RemoteFrame parent's 
ownership in the FrameTree -- instead of
freezing the whole DrawingArea. The detached frames are recorded on 
BackForwardCache's own CachedPage entry for that
identifier (BackForwardCache::setDetachedRootFramesForFrameItem / 
CachedPage::detachedRootFrames), and
restoreWithFrameItem reattaches them via Page::addRootFrame() on restore.

Testing this case surfaced two more, related bugs in the same code:
- Suspending the same, reused WebPage more than once before any restore 
(e.g.a.com/page1 -> page2 -> page3, each with
its own same-site iframe) silently skipped caching every suspend after the 
first, because suspendWithFrameItem guarded
on a single WebPage-wide "already suspended" bool instead of tracking each 
cached identifier separately. Fixed by keying
the detached-root-frame bookkeeping -- and the guard itself -- per identifier 
instead of per WebPage.

- Evicting a cache entry without ever restoring it (e.g. via prune() or 
_clearBackForwardCache) could remove the same
root frame a second time: the normal teardown (CachedFrame::destroy() -> 
Frame::detachFromPage() ->
Page::removeRootFrame()) doesn't know the frame was already detached from 
Page::rootFrames() by suspendWithFrameItem,
and tripped an assertion. Frame::detachFromPage() now only calls 
Page::removeRootFrame() if the frame is still actually
registered as a root frame.

Added regression tests for all three issues above.
Tests: SiteIsolation.MultiProcessBFCacheSameSiteReusedIframeNotFrozen
       SiteIsolation.MultiProcessBFCacheRestoreRerendersReattachedIframe
       SiteIsolation.MultiProcessBFCacheRepeatedSameSiteSuspendCachesEachEntry
       SiteIsolation.MultiProcessBFCacheSameSiteEvictionDoesNotCrashIframe

* Source/WebCore/history/BackForwardCache.cpp:
(WebCore::BackForwardCache::setDetachedRootFramesForFrameItem):
* Source/WebCore/history/BackForwardCache.h:
* Source/WebCore/history/CachedPage.h:
* Source/WebCore/page/Frame.cpp:
(WebCore::Frame::detachFromPage):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::suspendWithFrameItem):
(WebKit::WebPage::restoreWithFrameItem):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TestWebKitAPI::startCountingAnimationFrames):
(TestWebKitAPI::animationFrameCount):
(TestWebKitAPI::expectAnimationFrameCountToIncrease):
(TestWebKitAPI::(SiteIsolation, 
MultiProcessBFCacheSameSiteReusedIframeNotFrozen)):
(TestWebKitAPI::(SiteIsolation, 
MultiProcessBFCacheRestoreRerendersReattachedIframe)):
(TestWebKitAPI::(SiteIsolation, 
MultiProcessBFCacheRepeatedSameSiteSuspendCachesEachEntry)):
(TestWebKitAPI::(SiteIsolation, 
MultiProcessBFCacheSameSiteEvictionDoesNotCrashIframe)):

Canonical link: https://commits.webkit.org/318319@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to