Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: e23afe633acbe60a383dea12b39e33856b074239
https://github.com/WebKit/WebKit/commit/e23afe633acbe60a383dea12b39e33856b074239
Author: Basuke Suzuki <[email protected]>
Date: 2026-06-30 (Tue, 30 Jun 2026)
Changed paths:
A
LayoutTests/http/wpt/site-isolation/history-traversal/history-traversal-navigate-parent-while-child-loading-expected.txt
A
LayoutTests/http/wpt/site-isolation/history-traversal/history-traversal-navigate-parent-while-child-loading.html
M Source/WebCore/history/HistoryItem.h
M Source/WebCore/loader/HistoryController.cpp
M Source/WebKit/Shared/SessionState.cpp
M Source/WebKit/Shared/SessionState.h
M Source/WebKit/Shared/SessionState.serialization.in
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Source/WebKit/WebProcess/WebCoreSupport/SessionStateConversion.cpp
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
Log Message:
-----------
[Site Isolation] Per-frame back/forward walk regresses iframe to stale
initial about:blank
https://bugs.webkit.org/show_bug.cgi?id=317458
rdar://180077264
Reviewed by Sihui Liu.
Under UseUIProcessForBackForwardItemLoading,
WebPageProxy::dispatchPerFrameTraversals
walks the (current, target) BF frame trees and dispatches a per-frame
GoToBackForwardItem whenever itemSequenceNumber differs. When the target entry
holds the stale "initial about:blank" state for an iframe whose live document
has
since loaded a real URL, the walk dispatches a navigation back to about:blank
and
regresses the live iframe.
The HTML spec (https://html.spec.whatwg.org/#initialise-the-document-object)
requires the iframe's initial about:blank entry to be replaced by the iframe's
first real navigation, but WebKit's BF list does not propagate that replacement
to non-current entries. The legacy navigatedFrameID-heuristic routing path
masked the issue by never dispatching a per-frame iframe traversal in the first
place; the walk-as-replacement (https://bugs.webkit.org/show_bug.cgi?id=317090)
exposes it because it compares each frame's state pair-wise.
Reproduction is the imported WPT
imported/w3c/web-platform-tests/html/browsers/browsing-the-web/history-traversal/history-traversal-navigate-parent-while-child-loading.html
which performs a parent pushState() while an iframe is mid-initial-navigation,
then asserts on history.back() that the iframe URL is preserved. Without the
fix, the iframe regresses:
FAIL pushState() in parent while child is doing initial navigation, then go
back
assert_equals: expected "http://web-platform.test:8800/common/blank.html" but
got "about:blank"
This regression surfaces only when UseUIProcessForBackForwardItemLoading is
enabled under SiteIsolationEnabled, the configuration that PR #67459
(https://bugs.webkit.org/show_bug.cgi?id=316588) re-enables in the test harness.
Fix: introduce a walk-side guard isStaleInitialAboutBlankIframeTarget that skips
dispatching a per-frame traversal into a non-main child frame's stale initial
about:blank entry. The stale entry is identified by an authoritative
isInitialAboutBlank flag, not a URL-string match. The flag rides the existing
HistoryItem -> FrameState pipeline (mirroring
wasCreatedByJSWithoutUserInteraction):
HistoryController::initializeItem sets it from
DocumentLoader::isInitialAboutBlank(),
which is true only for the frame's initial empty document; toFrameState /
applyFrameState round-trip it through SessionState serialization. Because an
intentional iframe.src="about:blank" navigation happens after
committedFirstRealDocumentLoad() its DocumentLoader is not the initial empty
document, so its flag is false and the walk dispatches the traversal as a real
navigation. The earlier URL-string heuristic (toURL is empty or "about:blank")
could not distinguish the initial empty document from an intentional about:blank
load and so would have wrongly skipped the latter; the flag closes that gap.
A spec-level fix would be to propagate the initial about:blank replacement to
older BF entries when an iframe completes its first real navigation; that is a
separate follow-up bug and is not attempted here because it touches
BackForwardClient / HistoryController across processes and is out of scope for
this regression.
The imported WPT
imported/w3c/web-platform-tests/html/browsers/browsing-the-web/history-traversal/history-traversal-navigate-parent-while-child-loading.html
covers the behavior but shares the upstream baseline across configurations, so
it cannot pin SiteIsolationEnabled / UseUIProcessForBackForwardItemLoading via a
webkit-test-runner header and only exercises this fix once the test harness
auto-couples the flags (bug 316588). Add a http/wpt/site-isolation copy that
pins both flags in its header, so the regression is covered on this PR
independently of 316588. Verified negatively: the copy fails (iframe regresses
to about:blank) without this fix and passes with it.
Add an API test that covers the gap the flag closes, which the WPT above does
not: a child frame that navigates intentionally to about:blank after its first
real load, then back. With the old URL-string heuristic the back traversal into
that intentional about:blank entry was wrongly skipped and the child was
stranded on the prior real URL; with the isInitialAboutBlank flag it is
dispatched. Verified negatively: the test fails at the go-back assertion with
the old heuristic and passes with the flag.
*
LayoutTests/http/wpt/site-isolation/history-traversal/history-traversal-navigate-parent-while-child-loading.html:
Added.
*
LayoutTests/http/wpt/site-isolation/history-traversal/history-traversal-navigate-parent-while-child-loading-expected.txt:
Added.
* Source/WebCore/history/HistoryItem.h:
(WebCore::HistoryItem::setIsInitialAboutBlank):
(WebCore::HistoryItem::isInitialAboutBlank const):
* Source/WebCore/loader/HistoryController.cpp:
(WebCore::HistoryController::initializeItem):
* Source/WebKit/Shared/SessionState.cpp:
(WebKit::FrameState::FrameState):
(WebKit::FrameState::copy):
(WebKit::FrameState::replacePayloadFrom):
* Source/WebKit/Shared/SessionState.h:
* Source/WebKit/Shared/SessionState.serialization.in:
* Source/WebKit/WebProcess/WebCoreSupport/SessionStateConversion.cpp:
(WebKit::toFrameState):
(WebKit::applyFrameState):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::isStaleInitialAboutBlankIframeTarget):
(WebKit::WebPageProxy::dispatchPerFrameTraversals):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TestWebKitAPI::TEST):
Canonical link: https://commits.webkit.org/316161@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications