Skip to content

fix(engine-dom): strict classic 脚本顶层声明导出三重缺口,bing 全站 _w/_ge undefined 级联消除 - #133

Merged
leizongmin merged 2 commits into
mainfrom
bing-t2-strict-var-scope
Oct 11, 2026
Merged

leizongmin merged 2 commits into
mainfrom
bing-t2-strict-var-scope

Conversation

@leizongmin

@leizongmin leizongmin commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

解决了什么

打开 https://www.bing.com 时全站脚本崩溃(控制台 12+ 条 _w is not defined / _d is not defined / _ge is not defined 级联,站点错误处理器自身也崩),搜索结果页顶部导航与侧栏缺失。根因是 ZeroWeb 经间接 eval 执行 classic <script> 时,对带 "use strict" 的脚本建立独立变量环境(真实浏览器 Script Is A Global Code,顶层 var/function 恒建全局绑定,ECMA-262 §sec-scripts);既有的全局发布后缀机制在 bing 的两种真实形态下全部失效:

  1. strict 判定漏检前导注释:bing 全站脚本以 //<![CDATA[ 注释开头、指令在第二行(Directive Prologue 允许,V8 已按规范进入 strict eval),旧判定只认"首非空行恰为指令"→ 判定 sloppy → 零导出。
  2. 导出扫描按行首零缩进锚定:bing 的 32KB 压缩脚本全部顶层声明在单行中部(};;var _w=window,_d=document,...),行锚扫描全漏。
  3. 后缀被行注释吞掉:源码以 //]]> 结尾时,以 ; 拼接的导出后缀与注释同处一行被整体注释掉(wrapper 生成物打印实证:后缀已生成但 defineProperty 从未执行)。

修复(均在 crates/engine/src/js_dom_bridge/script_gen.rs):is_strict 改按 Directive Prologue 规则判定(跳过前导空白/行注释/块注释,序言多指令继续扫描);顶层声明导出改单遍字符状态机扫描(括号深度/字符串/模板字面量 ${}/注释/正则字面量感知,深度 0 语句边界匹配 var/function/async function/const/let/class,var 链按深度 0 逗号收集全部声明符);导出后缀分隔符 ; 改 \n。R147/R198/R201/M2-S2/R3254 既有导出语义逐项保留(var 仅 strict accessor、const 快照、let accessor、function/class 恒值、每名 try 包裹)。

怎么验证

  • 钉测红→绿(part49,5 例):CDATA 前缀 strict 单行 var 链(bing Bump the rust-patch group with 2 updates #6 形态主钉)、行中 function/async/generator/class/const/let、指令序言 6 变体(空行/行注释/单行块注释/跨行块注释/多指令)、var 链初始化器逗号+字符串/模板/函数表达式名负控、sloppy var 保持数据属性(R201 回归钉)。base(stash 法)4 钉红、修复后 6/6 绿。
  • 离线 fixture 重放(bing 首页 HTML 原样本地服务):_w/_d/_ge/_qs/_vs 全部恢复定义(修复前全 undefined)。
  • 真站:CDP console 错误事件 12 → 0;SERP(搜索"天气预报")结果 10 条不变、正文文本量 29393 → 32859(更多组件内容渲染);搜索输入+提交链路正常。
  • 回归:zero-engine lib 2970P/0F(含全部既有 R147/R198/R201/R3254 钉测);cargo fmt --all -- --check 无 diff;clippy -D warnings v8 腿与 quickjs 腿(--no-default-features --features quickjs)均通过;make test 全量 exit 0;WPT dom 套全量 55,085 Pass / 199 Fail——Fail 集合与 main 基线逐条 diff:唯一差异为 dom/events/Event-dispatch-click.html 文件级超时(基线同文件上轮已见时序 flaky,非本改动面;详见正文末尾说明)。
  • 环境注记:test_pipeline_deeply_nested_html 在 base 上即因测试线程默认栈 2MB 触发 SIGABRT(RUST_MIN_STACK=16M 即过),与本改动无关,已如实记录。

还有什么问题

优化前后截图

场景 / 问题 ID:bing 搜索结果页(www.bing.com/search?q=天气预报)JS 组件渲染(bing-20261010-r1 簇 C2)

优化前:ZeroWeb 优化后:ZeroWeb
改前:_w/_ge undefined 级联 12 条,顶部导航与侧栏组件缺失 改后:级联归零(console 12→0),导航/侧栏组件文本完整;favicon 与字体豆腐块等图片簇问题另行处理
优化前:bing SERP 优化后:bing SERP
  • 前图 / 后图版本:7fd20cb5d 基线二进制 / 174bd23

  • 捕获条件:https://www.bing.com/search?q=天气预报,viewport 1280×900,DPR 1.0,headless CPU 渲染,同机同负载窗口

  • 观察到的变化及剩余差异:JS 错误级联消除(console 12→0)、SERP 文本量 +11.8%;favicon 碎裂/输入框豆腐块等视觉簇仍在(另行处理);首页截图修复前后 md5 相同(其视觉问题由图片簇承担)

  • 全图附件:见正文附件(1280×900 全窗)

  • Chrome 参考:Chrome 154.0.8037.92 同检查点正常(cn.bing.com 变体;ZW 停留 www 变体为重定向 URL 簇 C1,另行处理)

  • 脱敏范围 / 附件内容核验 / PR 图片呈现核验:公开页面无敏感内容;附件与本地证据 md5 一致性在发布时核验

  • 已验证 best / PR head:174bd2314(分支 bing-t2-strict-var-scope,rebase 于 d2c909f)

  • 实验停止原因 / 截图交付状态:切片交付(bing 任务持续进行中)

独立审查

环节 报告状态 head / base 证据
测试有效性首轮 CHANGES_REQUIRED(历史报告) 01c327b / 52afb06 本地证据 SHA-256:1676ca73a0e6852879374d7420f410eea352886e5cdec01c7be5ad9e49183ae4
缺陷首轮 CHANGES_REQUIRED(历史报告) 01c327b / 52afb06 本地证据 SHA-256:84bdf8a058317ca84658e56ce53145cb5a536bf8fd6f12718c8a93c5b5b282fd
测试有效性复核 PASS(历史报告) 94173db / 52afb06 本地证据 SHA-256:ca40f2cc79c97631e7d8eb61cc2a0a0676d685cef4dadaea08038789b1fad87c
缺陷复核 PASS(历史报告) 94173db / 52afb06 本地证据 SHA-256:7f064d412f3d3fad397e46ea3c724620f3b4a1bc5b3c469cbd98a6af42d8c278
汇总 PASS(历史报告) 94173db / 52afb06 本地证据 SHA-256:9dc8c0584644bad9dd8e1be5badb2d006adca4b0aa0a4b2ff832902ebe64134d
缺陷复核 PASS 174bd23 / d2c909f 本地证据 SHA-256:e3cfcb1bb4c5dd09c81a6296eeea5f75fbcb6852f80a55cc80f25691ca871fca
汇总 PASS 174bd23 / d2c909f 本地证据 SHA-256:ea4c0c6904173d5b34d38ae0cb779944b973b09954ac919aabc7884f2d8aee4f

未解决阻断项:0。
报告保留在本地运行目录;以上为报告记录,独立性与交付就绪另由门禁核验。

@cursor

cursor Bot commented Oct 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: 6d77ffc3-6834-47be-b97c-eeebe65d5b90)

@cursor

cursor Bot commented Oct 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: a817f1b5-8464-4c9e-96dc-df66be9b5bce)

… 级联消除

classic <script> 经间接 eval 执行,strict 源在 V8 建独立变量环境,顶层 var/function
困在 eval 作用域(真实浏览器 Script Is A Global Code 恒建全局绑定,ECMA-262 §sec-scripts)。
既有导出后缀机制(R147/R198/R201/M2-S2/R3254)三处缺口,bing 全站内联脚本形态全部踩中:

1. is_strict 只认首非空行恰为指令——指令序言允许前导注释,bing 全站
   //<![CDATA[ 开头漏检 → 零导出。改为 Directive Prologue 规则判定
   (script_directive_is_strict:前导空白/行注释/块注释跳过,序言多指令续扫)。
2. 导出扫描行首零缩进锚定——bing 32KB 单行脚本的顶层声明全在行中
   (};;var _w=window,_d=document,... @col 26588)。改为单遍字符状态机
   (scan_top_level_decl_exports:括号/字符串/模板 ${}/注释/正则感知,
   深度 0 语句边界(含换行 ASI)匹配 var/function/async function/const/let/class,
   var 链按深度 0 逗号收全部声明符;R201/R147/R198/M2-S2 导出语义逐项保留)。
3. 后缀以 ; 拼接——源码以 //]]> 行注释结尾时后缀被整体注释吞掉
   (wrapper 生成物实证:后缀已生成但 defineProperty 从未执行)。分隔改 \n。

验证:part49 六钉 base 红→修复绿(CDATA/序言 6 变体/var 链负控/sloppy R201 钉/
WPT prefixed-animation-event-tests.js 无分号+换行 ASI 实形);engine lib 2971P/0F;
make test exit 0;clippy v8+quickjs 双腿 -D warnings 绿;WPT dom 套同日同机对照
55,084P/199F/16T vs base 55,083P/200F/16T——Fail 集合 diff 零新增红、净消除 1,
webkit-animation/transition 4 文件子测由 runAnimationEventTests is not defined 转为
4×4 Pass(文件级仍超时,基线同超时);bing 真站 console error 12→0、SERP 结果 10 条
正文 29393→32859;离线 fixture _w/_d/_ge/_qs/_vs 全恢复定义。
…控恢复+accessor 钉

缺陷首轮三阻断(均 V8 实测证实):
- D1 解构声明符 ——模式 { 进深度 1 后 RHS 首标识符误中 Name 相
  伪导出为 accessor,实测毒化 globalThis 致全页读取栈溢出。修:Name 相遇 /
  弃链(括号开臂判定——合法 var 声明符不可能括号开头),解构绑定名不导出
  (保守漏导出,注释披露)。
- D2 ——Name 相消费 = 后 prev_sig 误记 'x',正则判除法、内容当
  代码、内部逗号触发伪声明符导出(读取栈溢出)。修:prev_sig 记 '='。
- D3 伪名数字起头(/a,2/ 场景)值形式 globalThis.2=2 语法错误击杀整个 eval 源
  (sloppy 脚本级回归)。修:push_export 标识符合法性校验 + 恢复 R201 门控
  (sloppy 不生成 var 后缀——var 本泄漏全局,后缀冗余)。

测试有效性首轮 TV-1:恢复旧 is_strict 变异下全部测试绿的零保护缺口。补
t2_cdata_strict_var_accessor_not_snapshot_tv1(descriptor.get=accessor 断言 +
assign2 跨脚本再赋值流)——变异 A 实测 5 钉红。TV-2:注释前缀无指令 sloppy
负控钉。TV-3 记录不修(D1-D3 sloppy 臂已覆盖)。D4()后/按正则)/D5(顶层块内
var)保守权衡维持,注释如实披露。

验证:t2_ 钉 9/9 绿;变异 A(旧 is_strict)5 钉红;engine lib 2974P/0F;
make test exit 0;clippy workspace+quickjs 双腿绿;WPT 定向
webkit-animation-end-event 4P/0F、Document-createElement 794P/0F;fixture
_w/_d/_ge/_qs/_vs 全恢复;bing 真站 console error 0、SERP 10 结果。
@leizongmin
leizongmin force-pushed the bing-t2-strict-var-scope branch from 94173db to 174bd23 Compare October 11, 2026 03:20
@cursor

cursor Bot commented Oct 11, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: b5a85590-5709-4e1a-b908-a756846c6903)

@leizongmin
leizongmin merged commit 3d18c5e into main Oct 11, 2026
2 checks passed
@leizongmin
leizongmin deleted the bing-t2-strict-var-scope branch October 11, 2026 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant