fix(iframe): [PKG-IFRAME-03] release failed setup and bind message peers

This commit is contained in:
Harvey Zhao committed 2026-09-13 00:03:37 +08:00
1 parent b8d03e7366
commit b8cdafedd1
23 files changed
+7940 -32

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,65 @@
# PKG-IFRAME-03 connection and peer boundary checkpoint (doing)
Connection acquisition/release and packet/peer admission now have separate TS
modules. Entry calls them without changing own fields or the bound receiver.
Listeners are captured with their owning window and released once; request
cancellation runs in finally. Failed setup marks the partial instance destroyed,
releases partial registration and cancels reentrant sent/waiting requests. If
release also fails, the original constructor error remains the public result.
The parent processes native packets only from its configured iframe WindowProxy;
the child processes them only from window.parent. Null/non-object payloads and
non-string types are ignored. Source-less/null-source local onMessage calls,
empty-string generic types and invalid commit payload error serialization remain
supported. The explicit compatibility/trust decision is ADR-025 in
[iframe-message-boundary.md](../iframe-message-boundary.md).
The first boundary assertion run against the preceding committed build exposed
an accidental cross-realm object-prototype comparison in a positive control;
copying the packet into the test realm corrected that test without changing
production behavior. The final unchanged 18 boundary assertions against b8d03e73
pass 2 and fail 16. Candidate source plus previous 16 lifecycle assertions pass 34.
The preceding build fails all 12 actual Chromium boundary cases (three scenarios
and four origin relationships). Failure reports/results/traces are retained.
Browser cases use real same/cross-origin windows, actual HTTP302 redirects and
opaque sandbox origins, with foreign handshake/response/commit and malformed
messages. Separate normal wire controls pair actual npm plugin-iframe@1.0.0 and
initial workspace tool main builds with a candidate on either side. They do not
claim to secure a receiver still running old code, or to test player/media/demo
integration. Final build/node/browser/CI results live in the checkpoint record.
The first source browser run passed 51 and failed 9 redirect cases because a
route-only redirect target was not served by the actual HTTP fixture. The first
old-build redirect failures therefore cannot establish product behavior. Both
reports are preserved. The fixture now serves its child HTML and HTTP302 from
the local server, asserting the observed status and Location. With that fix,
the old build fails all 12 boundary cases at the intended peer/payload assertions,
and candidate source passes all 60 boundary/mixed-version cases. No production
change or timeout widening was used to repair the test setup.
No protocol fields, public declarations, dependencies, versions or targetOrigin
policy change. The additional window admission and ignored malformed packets are
intentional defect corrections under API-04/05/12, documented rather than hidden.
All other generic message and commit behavior remains protected by historical
and candidate tests. Package architecture and executable script entries are
updated in the same checkpoint.
PKG-IFRAME-03 remains doing: navigation and reinjection need document-generation
handling that preserves child inject-before-load ordering. Source WindowProxy
identity alone does not identify the currently loaded document. All three Iframe
risks stay open pending their remaining lifecycle/integration/distribution gates.
Revert this checkpoint and run the normal package build to roll back. No push,
tag or publication. Commit subject:
`fix(iframe): [PKG-IFRAME-03] release failed setup and bind message peers`.
Final source/main/legacy each pass 34 Node assertions. Browser source passes 60,
main 234 (144 historical + 30 lifecycle + 60 boundary/mixed), and legacy 90
(30 lifecycle + 60 boundary/mixed), with no skips or unhandled candidate errors.
Each boundary suite contains 36 actual peer/payload cases and 24 normal historical
wire combinations, including observed server 302/Location and opaque origins.
Full CI passes 1523 (1349 unit + 14 engineering + 160 baseline), 44 repeated
contracts and 328 production TS files. Three import/SSR files pass. Final source,
artifact, old Git build, report hashes and byte-identical docs copies are checked.
Task remains doing; no risk closure or release claim. This task began 2026-09-12;
completion of this checkpoint is timestamped in the validation record.
+4
View File
@@ -32,6 +32,10 @@
## 开始实现前需补齐的决定
ADR-025:Iframe绑定实际父子窗口,保留跨源/重定向/opaque-origin与公开local receiver,
同时拒绝无关窗口和无效消息。独立依据、兼容影响与剩余信任限制见
[Iframe消息边界](iframe-message-boundary.md);本轮不将来源绑定视为导航或全包发布验收。
1. 支持的历史核心/插件版本、TS 最低版本与浏览器能力矩阵,由 BASE-01/ENG-01 登记证据。
2. 连续切源、销毁中 Promise 的结果与错误策略,由 CORE-04/CORE-09 的变更记录明确。
3. 真机与外部 SDK 验证环境、负责者和缺失检查的发布处理,由 ENG-05/REL-03 明确。
+45
View File
@@ -0,0 +1,45 @@
# ADR-025:Iframe 的消息对端与公开调用边界
关联:PKG-IFRAME-03/05,IFRAME-TRUST-01;2026-09-12。
状态:已实现方向,浏览器/最终构建结果以本轮验证记录为准;不是全包发布准入。
## 证据和选择
IFRAME-01冻结旧npm与初始工作区契约,02用真实WindowProxy复现了无关窗口冒充
inject、响应和可执行commit。构造参数明确指定iframe/url,仓库demo使用父页实例与
该子页inject配对;没有把所有无关窗口当作合法对端的公开功能说明。
据此将实际浏览器消息限定到所选窗口:父实例比较event.source与其$iframe.contentWindow,
子静态receiver比较event.source与window.parent。非对端消息在更新injected、结算请求、
调用message回调和执行commit之前被忽略。对端绑定是已有定向通信的缺陷修正。
这是明确记录的安全行为差异,不把历史误接收永久冻结为支持承诺。
不固定最初URL的origin,不修改targetOrigin='*'。固定初始origin会拒绝现有跨源配对、
跳转后的选定子窗口或sandbox opaque-origin;本轮分别用真实同源/跨源、HTTP302和
allow-scripts sandbox测试这些情况。窗口身份绑定不意味着验证该窗口当前内容的可信度。
父页必须信任选定iframe中的内容;注入子页必须信任其嵌入父页。自动允许任意父页执行
commit的部署风险不能通过“它确实是parent”消除,部署准入仍需独立审查。
公开onMessage仍允许local caller直接调用,source缺省或null时保留原方法用途。
此路径也允许具有本页脚本权限的代码自行构造事件;它不提供同页脚本隔离。验证测试的
跨窗消息均来自真实浏览器postMessage,不用source-less合成事件冒充已证明的来源校验。
## 消息与版本兼容
- 方法、公开字段/描述符、绑定receiver、type/data/id封套和resove保持原样。
- 对端的非null对象且type为string才参与协议;空字符串type仍是合法generic消息。
- 既有非error同ID响应继续结算;commit函数体/resolve约定及异常发包/拒绝通道不替换。
- 旧npm主类和初始workspace主类分别在父/子两侧与候选配对,检查普通同步和异步往返。
这些对照证明旧wire可互通,不证明未升级一侧的来源检查已修复;完整防护需升级双方。
- 无关窗口的message通知、伪造响应/commit及无效封套的回调/崩溃被主动消除。
如果应用确实需要收集其他窗口消息,应在自己的window message监听器中明确管理其对端;
不再依赖本工具对任意窗口的历史误处理。
- 尚未处理导航握手代际;WindowProxy可跨导航保持身份,不能把来源绑定当作文档身份校验。
PKG-IFRAME-03继续处理,IFRAME-05验证完整新旧核心/demo组合,风险未因本检查点自动关闭。
## 验证与回退
`test/iframe-boundaries.test.js`覆盖来源、畸形封套、local receiver、setup与destroy失败,
`test/browser/iframe-boundaries.spec.js`覆盖真实浏览器和旧wire组合。
验证记录:`baselines/iframe-boundaries-checkpoint.json`;历史失败必须与候选验收分开。
没有新增依赖、选项、公共类型或包版本。回退本检查点后用正常build重建产物;初始基线保留。
+1 -1
View File
@@ -532,5 +532,5 @@
- PKG-MB-09: [记录](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) [记录](baselines/mb-native-pip-checkpoint.json) [记录](changes/2026-09-12-PKG-MB-09-sustained-playback-checkpoint.md) [记录](baselines/mb-sustained-validation.json) [记录](baselines/mb-sustained-media.json)
- PKG-IFRAME-01: [记录](changes/2026-09-12-PKG-IFRAME-01-contract.md) [记录](baselines/iframe-release.json) [记录](baselines/iframe-contract.md) [记录](baselines/iframe-contract-validation.json)
- PKG-IFRAME-02: [记录](changes/2026-09-12-PKG-IFRAME-02-behavior.md) [记录](baselines/iframe-behavior-validation.json)
- PKG-IFRAME-03: [记录](changes/2026-09-12-PKG-IFRAME-03-requests-checkpoint.md) [记录](baselines/iframe-requests-checkpoint.json)
- PKG-IFRAME-03: [记录](changes/2026-09-12-PKG-IFRAME-03-requests-checkpoint.md) [记录](baselines/iframe-requests-checkpoint.json) [记录](changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md) [记录](baselines/iframe-boundaries-checkpoint.json) [记录](iframe-message-boundary.md)
- PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据
## PKG-IFRAME-03 构造清理与窗口来源检查点(doing)
增加connection/protocol两个严格TS模块;构造失败清理监听和重入请求,destroy即使
移除监听报错仍取消请求。父/子仅处理选定对端的原生消息,忽略畸形封套;保留local
onMessage、空type、自定义响应及旧commit协议。ADR-025记录来源绑定、跳转/opaque
兼容与仍需信任嵌入父页的限制,未把WindowProxy身份误称作文档身份或代码沙箱。
新18断言对上一提交2通过/16失败,候选连同原生命周期各34通过;旧构建实际Chromium
12项全部失败。修复HTTP测试夹具后,源码浏览器60、正式main234、legacy90通过;
每份边界矩阵含36来源/封套及24旧npm/工作区父子互通,未声称未升级一侧已被修复。
完整CI1523与44重复契约、3导入/SSR通过,328生产TS;哈希与docs副本均一致。
见[决策](iframe-message-boundary.md)、[变更](changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md)
和[验证](baselines/iframe-boundaries-checkpoint.json)。222项:107 done、10 doing、105 todo。
本地检查点提交。下一步导航/重新注入的文档代际与inject-before-load时序;三个风险仍open。
## PKG-IFRAME-03 请求资源与TS入口检查点(doing)
入口和请求管理拆为2个严格TS模块,保留7个公开字段及resove/回调/消息协议。
+9 -4
View File
@@ -3775,7 +3775,7 @@
],
"status": "open",
"confirmation": "reproduced",
"compatibleResolution": "Request ownership checkpoint fixes timestamp collisions, polling/send failures and terminal destruction while preserving public resove/registry/envelopes. Navigation/reinjection and setup failure cleanup remain for PKG-IFRAME-03; keep open until complete actual iframe lifecycle acceptance.",
"compatibleResolution": "Owned requests fix collision/polling/send/destroy failures; connection cleanup now releases partial construction and cancels requests even if listener removal fails. Navigation/reinjection and document-generation handling remain for PKG-IFRAME-03; keep open until complete actual iframe lifecycle acceptance.",
"closureCriteria": "Old behavior and candidate fixes have deterministic race/resource tests plus actual iframe integration.",
"evidence": [
"refactor/baselines/iframe-contract.md",
@@ -3784,7 +3784,9 @@
"refactor/baselines/iframe-behavior-validation.json",
"refactor/changes/2026-09-12-PKG-IFRAME-02-behavior.md",
"refactor/changes/2026-09-12-PKG-IFRAME-03-requests-checkpoint.md",
"refactor/baselines/iframe-requests-checkpoint.json"
"refactor/baselines/iframe-requests-checkpoint.json",
"refactor/changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md",
"refactor/baselines/iframe-boundaries-checkpoint.json"
]
},
{
@@ -3796,14 +3798,17 @@
],
"status": "open",
"confirmation": "reproduced",
"compatibleResolution": "Treat message origin/source and executable commit as an explicit compatibility and trust-boundary decision; do not silently replace the protocol during TS conversion.",
"compatibleResolution": "ADR-025 binds native messages to the selected iframe/parent and rejects malformed envelopes while preserving local receiver calls and same/cross/redirect/opaque origins. Executable commit still trusts the embedding parent and selected content; navigation/document generation and complete integration/release review remain open.",
"closureCriteria": "Controlled and real same/cross-origin evidence plus an explicit documented compatibility decision and supported trust model.",
"evidence": [
"refactor/baselines/iframe-contract.md",
"refactor/baselines/iframe-release.json",
"refactor/changes/2026-09-12-PKG-IFRAME-01-contract.md",
"refactor/baselines/iframe-behavior-validation.json",
"refactor/changes/2026-09-12-PKG-IFRAME-02-behavior.md"
"refactor/changes/2026-09-12-PKG-IFRAME-02-behavior.md",
"refactor/changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md",
"refactor/baselines/iframe-boundaries-checkpoint.json",
"refactor/iframe-message-boundary.md"
]
},
{
+4 -1
View File
@@ -3662,7 +3662,10 @@
"acceptance": "结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过",
"evidence": [
"changes/2026-09-12-PKG-IFRAME-03-requests-checkpoint.md",
"baselines/iframe-requests-checkpoint.json"
"baselines/iframe-requests-checkpoint.json",
"changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md",
"baselines/iframe-boundaries-checkpoint.json",
"iframe-message-boundary.md"
]
},
{