Files
OpenTerminal/tests
Bill c6aca15134 fix(highlight): ReDoS 改用静态结构分析根治;fit 加耗时埋点
## ReDoS:从「限制损害」改为「阻止发生」

原防线(MAX_PATTERN_LEN 限幅 + 编辑器实跑探测)都拦不住真正的灾难性回溯:
`(a+)+$` 配 30 个字符实测 8.2 秒,而 MAX_LINE_LEN=4KB 限的是长度不是回溯成本。

两个候选方案都被实测否决:
- re2:不支持 lookbehind,会废掉 perm/okstate/http 三条依赖它的预设——
  治了病废了功能
- Worker + 超时:往返开销 0.11ms/块(直接执行 0.035ms,4.1x),且终端高亮
  必须同步(WriteBatcher 消费同步染色结果),异步化会打乱 HighlightStream
  的 carry/flush 语义

采用静态结构分析 isReDoSProne():编译期扫描两种可证危险的形状——嵌套量词
((a+)+ / (.*)* / ([a-z]+)*)与同分支重复((a|a)*),命中即拒绝该规则,
不进编译集,永远到不了热路径。开销是纯字符串遍历。

关键细节:
- 有界量词不算危险:(?:\d{1,3}\.){3}(ipv4 预设)外层 {3} 固定重复,不会
  指数回溯。只对 *、+、{n,} 这类开放式重复判定。曾因把 {n} 也算进去误杀 ipv4
- 断言组((?= (?<= (?<!)不是重复单元,跳过

实测 9/9 危险全抓、6/6 安全无误判、22 条出厂预设全部通过。编辑器改用同一
函数,警告在用户输入时出现而不是等预览卡住。

## fit 耗时埋点

stall 日志(10-14 至 10-17 每天 23-67 次,平均 27.5 秒,34/35 是渲染线程)
经查证是 v1.0.29 之前就存在的既有问题,与本轮改动无关。高亮引擎已排除
(512KB 仅 0.3ms)。

真正候选是 fit 的全量 reflow(代价正比 scrollback 行数),但通用 stall 看门狗
只会说「渲染层卡了」,不可行动。故给 scheduleFit 加耗时记录:超 200ms 写诊断
日志,含 cols/rows/scrollback。正常路径只多一次 performance.now()。

不盲改 reflow 逻辑——先有数据再优化。
2026-10-17 22:43:49 +08:00
..