ladybird/Tests/LibWeb/Text/input/HTML/load-during-session-history-push-drain.html
sideshowbarker e61a91c017 LibWeb: Keep session history coherent when navigations jump the queue
Problem: A document could drop a load if it ran a stream of synchronous
same-document history navigations (say, a pushState flood) while it was
concurrently loaded again. The load never finished — so on sanitizer/
slow builds, this had been intermittently taking down unrelated tests in
CI — since test-web reuses one WebContent process, and the next test’s
load can arrive while the previous document’s history work is still
draining. A synchronous commit also claimed a session history step it
never retired — so claimed steps piled up without bound.

Cause: A sync same-document navigation committed immediately and could
jump the session-history-traversal queue while a queued apply-history-
step — such as a cross-document load — was still waiting behind it. The
queued run read the active session-history entry after the sync
navigation had installed it, but before its step number was assigned —
then judged itself stale against that still-pending step, and was
discarded. The shared step numbering was fragile under the same nesting:
A number computed from the current step alone could collide with an in-
flight one — and a stale run that completed later could write its own
step back over a newer one. 394312ab5a stopped the crash this used to
cause, but the races remained.

Fix: Treat a queued push whose displayed entry’s step is still pending
as live rather than stale — so the concurrent load isn’t dropped. Number
apply-history-step runs, and let a run commit its target step only if no
newer run has committed one — so a stale run can’t move the current step
backwards. Claim each new step past every claimed-but-uncommitted step —
rather than from the current step alone, and keep clearing the forward
session history from removing those entries. And retire the step a sync
commit claims, since it applies in the same task, and nothing else will.

See https://github.com/LadybirdBrowser/ladybird/issues/10028
2026-06-17 12:25:53 +02:00

19 lines
519 B
HTML

<!DOCTYPE html>
<script src="../include.js"></script>
<body>
<script>
asyncTest(done => {
if (location.search.includes("loaded")) {
println("PASS (didn't crash)");
done();
return;
}
document.body.appendChild(document.createElement("iframe"));
history.pushState({}, "", "#pushed");
const next = new URL(location.href);
next.search = "?loaded";
next.hash = "";
internals.loadURL(next.href);
});
</script>
</body>