Skip to content

fix(runtime): preserve child refresh, detached Window, hash navigation, and CSP - #1726

Closed
ldm0 wants to merge 8 commits into
mainfrom
bump-version1118
Closed

ldm0 wants to merge 8 commits into
mainfrom
bump-version1118

Conversation

@ldm0

@ldm0 ldm0 commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

This combined runtime PR has been superseded by four independent PRs targeting main:

PR Scope Final local Nextest result
#1661 Child meta refresh load/adoption ordering 20,443 passed, 18 skipped
#1783 Cold lazy surfaces on retained detached Window globals 20,434 passed, 18 skipped
#1786 Same-document Location.hash setters 20,436 passed, 18 skipped
#1790 Image CSP self matching in inherited local documents 20,434 passed, 18 skipped

Each branch is based directly on the fixed main baseline ce0781f2ad7e3ab62198ef169c06ed72d9e4b178 and passed formatting, workspace/all-targets/all-features Clippy with warnings denied, and full Nextest before its new Rust commit was created. The 17 source/test paths are disjoint. Recombining the patches exactly reproduces this PR's source changes on that baseline; original authors and source-commit traceability are retained.

All four remote heads and online PR file lists were verified. Closing this aggregate PR avoids submitting the same runtime fixes twice. The Taffy/Stylo work remains in #1745.

The original bump-version1118 branch remains at 44621a04398ceb3e741ac475d517dc2eddbce0bb, including its combined Release Cases snapshot. That historical snapshot has not been copied into the standalone source PRs; regenerate Cases from the integrated Release after merging the relevant fixes.

Historical combined-build description and evidence

Preserve child-document load/refresh ordering, retained Window surfaces, and same-document hash navigation. Restore image CSP self matching for inherited local documents while keeping owner-document enforcement.

Changes

  • Keep child meta refresh through initial owner-load delivery, callbacks that insert or replace refresh directives, and later mutations in loaded documents.
  • Materialize previously unread lazy surfaces on retained detached Window globals in their original Realm, preserving receiver checks and SameObject behavior.
  • Keep hash clearing and equivalent encoded-fragment assignments in the current Document. Preserve normal full-URL navigation behavior and srcdoc document identity.
  • Match image CSP sources in inherited about:blank/srcdoc documents against the creator URL. Keep the actual document URL in violation reports, opaque sandbox origins, data-URL blocking, cache rechecks, and owner-specific reporting.
  • Add a CSP regression guard covering ordinary/sandboxed srcdoc, changed parent/child base URLs, permitted same-origin images, blocked cross-origin images, and reporting.

The Taffy/Stylo upgrade, required shared-atom/parser compatibility, and all layout/style fixes are in #1745. This branch has 17 source/test files and no source-path overlap with that PR. Cargo manifests/lockfile, layout, CSS parser, and selector code remain at the validated main baseline.

CSP regression boundary

PR #1714, merged 2026-10-19 14:37:13 UTC, introduced the regression in 5399724fb07a24935531b92c42621be1baa8c089.

For content-security-policy/meta/sandbox-iframe.html, a Release with only that commit removed, while holding all six runtime fixes constant, passes 3/3. The build containing it fails 3/3. The adjacent parent is 2843cde2c43b418fc96c60541ae1ff6971a5fe41. Chromium passes the sandboxed-srcdoc and opaque-data-origin controls. The final fix passes both cases in three fresh rounds and preserves #1714's document ownership and reporting behavior.

The new CSP fix is its own commit, 59c8fc213350fd4d00ac06c3ce0eed5a3971a999. Six earlier runtime commits retain their original topics/authors and an Original-commit trailer. The Cases snapshot is separate in 44621a04398ceb3e741ac475d517dc2eddbce0bb.

Validation

Validated independently on main@5399724fb07a24935531b92c42621be1baa8c089, using final source contents matching 59c8fc213350fd4d00ac06c3ce0eed5a3971a999.

  • Release build and cargo fmt --all passed.
  • cargo clippy --workspace --all-targets --all-features -- -D warnings passed.
  • cargo nextest run --no-fail-fast: 20,407 passed, 18 skipped, including the new CSP guard.
  • Final WPT Cross at db95fafd1fcef8428805e41eb5705d444e8c67ce: 9,751 pass, 3,604 fail, 242 timeout, 24 harness-stalled, 9 error, 1 crash; 0 missing. Cases exactly partition all 13,631 results, and the CSP regression case is Pass.
  • Frozen Release SHA-256: a1a0396f693f7214c7f018565cc1b06039981192fafb9bc59daff07c32549dc9.
  • Three-binary/three-round checks of 14 lost Passes from the earlier combined build account for five moved runtime fixes, eight snapshot/timing variations, and the single main CSP regression fixed here.
  • Recombining both PRs reproduces the original combined sources plus the fixed main baseline, with only this three-file CSP fix added.

Both PRs are based directly on the same fixed main commit. Each shared Cases snapshot describes its own standalone binary; refresh the snapshot after combining both PRs.

@ldm0 ldm0 added the 1.1.19 label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Sequential Navigation Soak A/B

✅ HEAD completed the 200-navigation resilience and memory observation.

One browser process, one target, and one CDP session navigate CSDN → SegmentFault → Huaban → example.com repeatedly. This run issued 200 Page.navigate commands per binary.

Common ancestor 5399724fb0 → HEAD 44621a0439; benchmark order: head-first; workflow: success.

Session resilience

Metric Base HEAD
Attempted / planned 179 / 200 200 / 200
Direct observable pass 176 / 179 200 / 200
Failures / recovered 3 / 2 0 / 0
Recovery failures 1 0
Lifecycle order violations 0 0
Network order violations 0 0
Wall time 1,590.3 s 1,626.5 s

A public-page failure is reported separately from an unrecoverable session. The soak requires all navigation attempts, zero failed recovery, zero lifecycle/network ordering violations, and complete resource evidence.

Process-tree memory

Metric Base HEAD Δ
Boundary samples 179 200 21
Boundary RSS samples 179 200 21
Boundary PSS samples 179 200 21
Periodic peak RSS 216.6 MiB 223.9 MiB +7.3 MiB
Periodic peak PSS 213.8 MiB 220.7 MiB +7.0 MiB
RSS · first 10 avg 145.4 MiB 153.1 MiB +7.7 MiB
RSS · last 10 avg 108.1 MiB 157.0 MiB +49.0 MiB
RSS · last − first window -37.4 MiB +3.9 MiB +41.2 MiB
RSS · warm slope / 100 nav -15.0 MiB +3.8 MiB +18.8 MiB
PSS · first 10 avg 142.5 MiB 149.7 MiB +7.2 MiB
PSS · last 10 avg 106.1 MiB 153.9 MiB +47.8 MiB
PSS · last − first window -36.4 MiB +4.2 MiB +40.7 MiB
PSS · warm slope / 100 nav -14.5 MiB +4.2 MiB +18.7 MiB
Peak file descriptors 54 54 0
Peak threads 29 29 0

HEAD memory by 50-navigation quarter

HEAD range Avg RSS Final RSS Peak RSS Avg PSS Final PSS Peak FD
1–50 151.4 MiB 144.0 MiB 187.3 MiB 147.8 MiB 140.7 MiB 47
51–100 154.2 MiB 114.9 MiB 179.1 MiB 150.7 MiB 111.4 MiB 47
101–150 157.7 MiB 147.2 MiB 187.1 MiB 154.5 MiB 144.8 MiB 48
151–200 158.0 MiB 120.4 MiB 184.3 MiB 154.9 MiB 117.3 MiB 46

Raw reports and per-navigation boundary samples: workflow run and full sequential-navigation-soak-results artifact.

Public-site timing and memory are observational. Use the A/B deltas and trend shape as evidence, not as a deterministic performance threshold.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Spider Bench A/B

⚠️ Spider Bench infrastructure failed before a comparison could be produced.

Workflow: failure. Inspect the workflow run for the failing build, harness, or artifact step.

No benchmark result or performance conclusion is available for this run.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

CI Regression Report

Source CI run · source state at render: failure · artifacts: 3/6

Check Status Signal
Release regression ✅ HEAD/base failures 0/0; raw binary +0.005685%
Frontend differential ⚪ artifact unavailable or invalid
Agent episodes ⚪ artifact unavailable or invalid
Runtime/CDP contracts ✅ 26 contract cases; 0 failures
CDP smoke ⚪ artifact unavailable or invalid
WebMainBench ✅ 545/545 completed; 0 unexpected failures
Release regression — ✅ HEAD/base failures 0/0; raw binary +0.005685%

Package and image size

Metric Base HEAD Delta Delta %
Raw binary 153.27 MiB 153.28 MiB +8.92 KiB +0.005685%
Stripped binary 106.54 MiB 106.55 MiB +8.00 KiB +0.007333%
gzip binary 52.78 MiB 52.79 MiB +3.76 KiB +0.006965%
Rootfs 160.17 MiB 160.18 MiB +10.00 KiB +0.006097%
gzip rootfs 61.83 MiB 61.84 MiB +2.89 KiB +0.004564%

Startup latency and PSS

Case Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta
Serve ready 27.16 ms 27.80 ms +0.63 ms 4.74 MiB 4.67 MiB −75.00 KiB
CDP first page 50.53 ms 50.82 ms +0.28 ms 4.68 MiB 4.83 MiB +154.00 KiB
CDP warm page 12.37 ms 11.42 ms −0.95 ms 51.83 MiB 52.13 MiB +311.00 KiB
CLI about:blank 38.81 ms 39.29 ms +0.48 ms 3.91 MiB 4.80 MiB +908.50 KiB
CLI local JS 44.64 ms 43.17 ms −1.46 ms 4.36 MiB 5.36 MiB +1023.00 KiB

Concurrency matrix

Concurrency Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta HEAD failures Unstable B/H
1 41.66 ms 40.75 ms −0.91 ms 1.08 MiB 1.20 MiB +123.00 KiB 0 0/0
5 42.31 ms 42.14 ms −0.17 ms 1.70 MiB 5.30 MiB +3.60 MiB 0 0/0
10 41.59 ms 40.95 ms −0.63 ms 1.68 MiB 1.73 MiB +47.00 KiB 0 0/0
25 42.11 ms 41.45 ms −0.67 ms 4.00 MiB 1.77 MiB −2.23 MiB 0 0/0
100 41.39 ms 40.87 ms −0.52 ms 1.70 MiB 1.76 MiB +59.00 KiB 0 0/0
Frontend differential — ⚪ artifact unavailable or invalid

Artifact unavailable or invalid. See the source CI run for infrastructure details.

Agent episodes · Moli vs Chromium — ⚪ artifact unavailable or invalid

Artifact unavailable or invalid. See the source CI run for infrastructure details.

Runtime and CDP session contracts — ✅ 26 contract cases; 0 failures
Suite Cases Failures Median case p50 Median case p95 Median peak PSS p50
Synthetic fetch 13 0 250.23 ms 257.63 ms 35.82 MiB
Long-lived CDP session 13 0 56.72 ms 64.25 ms —
CDP smoke — ⚪ artifact unavailable or invalid

Artifact unavailable or invalid. See the source CI run for infrastructure details.

WebMainBench · 545 pages — ✅ 545/545 completed; 0 unexpected failures
Completed Successful Expected DNS failure Unexpected failures Panics Crashes Timeouts Empty output
545/545 544 1 0 0 0 0 0

Frozen HTML · Linux · --wait done · 45 seconds per page · no retries. Content quality is evaluated separately.

Diagnostics: webmainbench-results — every page's Markdown, stderr, and exit status. Source run and artifacts

All artifact fields are parsed by the trusted default-branch renderer; missing or invalid inputs remain visible as unavailable.

ldm0 added 8 commits October 20, 2026 04:46
Register the child document refresh before dispatching Window and owner-element
load callbacks. A callback can adopt the meta element into another iframe;
rescanning afterward lost the original refresh depending on frame load order.
The existing exact-document timer owner and navigation cancellation still apply.

Add deterministic source-first and destination-first iframe tests, including
adoption into an already loaded sandboxed document. The source-last case fails
before this change while the destination-last control passes. The old ordering
is present at least as far back as the earliest visible Public preview commit
27b5135, rather than a newly introduced feature change.

Validation:
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast

Original-commit: 1136e87
Keep the pre-load registration that preserves refreshes across meta adoption,
and also scan after owner load callbacks when no refresh is armed. This retains
support for callbacks that insert a new refresh without canceling the original
document's refresh when its element was moved or removed.

Add deterministic Window-load and iframe-load insertion tests. Both fail before
this fix, and the full Release WPT probe also exposed dynamic-append.html timing
out at 7e79f9c; that incomplete validation was stopped before Cases refresh.

Fixes: 7e79f9c (fix(html): arm child meta refresh before load callbacks)

Validation:
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast

Original-commit: 6d1bc4e
Route native meta insertion and attribute mutation candidates by their owning
document, instead of limiting mutation refresh handling to the top document.
Loaded child documents now register adopted or inserted refresh elements using
their own URL, sandbox policy and exact document timer owner. Ignore shadow-tree
candidates and retain the existing deadline for identical refresh candidates.

Use the active runtime borrow directly while registering child timers and create
the native callback in the child Window realm. Initial load capture remains the
fallback for child documents that are still loading.

Add deterministic source-first/source-last sandbox adoption tests and post-load
insertion and shadow-tree controls. The old frozen Release also reproduces the
related allow-scripts-flag-changing-1 WPT flake (7 pass/3 timeout in10 rounds);
the new source-last adoption and post-load insertion tests fail before this fix.

Validation:
- 13 related child meta refresh tests pass
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast

Original-commit: 0e34b9e
Capture refresh candidates during parsing and load callbacks as document-owned
pending work, then arm their timers only after the iframe owner load callback
finishes. DOM readyState complete alone does not establish that load callbacks
have run, so immediate mutation timers could change a fragment before the first
iframe load observed the original URL.

Use FrameOwnerStore's exact-document load progress to admit timer activation.
Keep pending candidates when meta elements move, preserve active deadlines for
identical candidates, and cancel both pending and armed work on retirement.

Add a Browser integration test that reproduces the premature fragment change,
and a Page task-executor ordering control. WPT same-document-refresh.html passes
with bec88e1 and fails with6faf8d3fed2 before this fix.

Fixes: 6faf8d3 (fix(html): schedule refresh mutations in loaded child documents)

Validation:
- 15 related child refresh and Browser integration tests pass
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast

Original-commit: 2fbc805
A retained child's original SameObject getter captured undefined when
its lazy surface had never been read. Returning that snapshot after retirement
made Window.screen disappear when an iframe was removed before its first read.

Use captured objects when present, and let the exact retained native global
materialize an untouched surface in its original Realm. Retain receiver and
cross-origin authorization. Cover cold Screen reads, identity and zero geometry.

Fixes: 9f11881 (PR #1651)

Validation of the complete fix set, with unchanged source content across
the separate logical commits:
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast: 20374 passed, 18 skipped

Original-commit: d61a6c8
Clearing Location.hash produced a URL without a target fragment and
entered the full-URL navigation path, interrupting load/harness completion and
replacing srcdoc documents. Preserve explicit hash-setter intent in the shared
Location route and compare encoded fragments before taking any navigation.

Keep the main branch's full href/assign no-fragment behavior and retired-facade
checks. Cover top-level hash removal, canonical hash reassignment, and srcdoc
Document identity, origin and NavigateEvent metadata.

Fixes: 536fa76 (PR #1701)

Validation of the complete fix set, with unchanged source content across
the separate logical commits:
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast: 20374 passed, 18 skipped

Original-commit: 5fe0217
Use the creator URL for source matching in inherited about:blank/srcdoc
documents. Keep actual document URLs in violation reports and preserve
opaque sandbox origins and data URL blocking.

Cover ordinary and sandboxed srcdoc, changed parent/child base URLs,
allowed same-origin images, blocked cross-origin images, and owner reports.

Regression-commit: 5399724
Regression-PR: #1714
@ldm0
ldm0 force-pushed the bump-version1118 branch from c4313c0 to 44621a0 Compare October 19, 2026 20:47
@ldm0 ldm0 changed the title feat(layout): upgrade Taffy to 0.15 and Stylo to 0.22 with regression fixes fix(runtime): preserve child refresh, detached Window, hash navigation, and CSP Oct 19, 2026
@ldm0 ldm0 closed this Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant