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