fix(web): 链接正则的嵌套量词让某个会话打开即卡死(D95) - #57
Merged
Merged
Conversation
`INLINE` 第 3 组(markdown 链接)的 label 是 `(?:[^\[\]\n]+|\[[^\]\n]*\])+`, 内层贪心 `+` 与末尾 `+` 叠成歧义:同一段标签有指数级切分方式。md 逐行送 `inlineInto`,所以只要某一行里有一段够长的 `[…]` 后面不是 `](`,引擎要 穷举完所有切分才认输,主线程回不到事件循环 → Chromium 报「页面无响应」。 会话 c24330ab(名字 bug)第 23 条 tool 结果里那行 `… || [...this.termTabs.get(this.termActive))` 就够:111 字符、最长内层 80 字符,旧正则单次 1434ms、新 0.04ms。前 61 条里共有 6 行这种文本, 整页渲染串起来就是十几秒起步的白屏。 改为逐字匹配 `(?:[^\[\]\n]|\[[^\]\n]*\])+`(Pike 式 `A|B` 重复,无歧义), `inlineInto` 里取 label 的那条同步改。接受的语法集合不变。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
INLINE里只有链接那一组的 label 是嵌套量词,其余六组都已经是A|B重复。把内层的贪心+去掉即可(Kleene 闭包同语言,只去掉歧义):inlineInto里取 label 的那条正则(/^\[((?:…)+)\]\(([^\s)]+)/)同步改,一处 2 行。为什么只有它会卡死:
renderMarkdown是一行一行送进inlineInto的。(x+|\[…\])+对同一段标签文本有 2^n 种切分,而 link 分支在整行里逐个位置尝试匹配;只要这一行里有一段够长的[…]后面不是](,引擎就得把所有切分试完才认输——主线程不再回到事件循环,Chromium 就报「此页面没有响应」。踩到的是会话
c24330ab…(名字bug)第 23 条 tool 结果里的一行 TypeScript:111 字符、
[之后最长内层 80 字符,没有](。第 1–22 条都能画,画到这一条页面就永久白屏。user 消息不走这条路(
web/src/chat.ts里body.textContent = item.text纯文本渲染),所以带图消息里的[Image: …]注释不触发;触发的一律是 tool 输出里的代码 / JSON / ANSI 构建日志。Evidence
snap.jsonitem#23,111 字符)喂旧正则,单次执行 1434 ms 不返回;整页 headless 打开该会话page.evaluate永不返回、page.screenshot15s 超时(渲染器死循环)。该会话前 61 条里就有 6 行这种文本(item#23 两处、feat(notes): 顶栏 🐞 记录——四类随手记、粘贴截图、归档 / 垃圾箱、三个出口(#55,D108) #56 的 ANSI 构建日志、表格预览:xlsx/xlsm/csv/tsv 当表打开 + 单元格编辑(patch 写回,保住图表) #73 的[{"text":"docs/DECISIONS.md",…}]等),整页渲染串起来是十几秒起步的白屏。After: 同一行 0.041 ms(约 35000×)。整页 headless 打开该会话:1.5s 内渲染完 159 条消息 / 4366 个 DOM 节点;同法复测另外三个会话
90da6b98(703 条)、b76727ed(568 条)、1efeff34(233 条)全部正常:[a](b.md)、[label with [inner] text](u)、[[a]b](u)、](b)这种嵌套、[x] (y)、、103/300 字符 label、中文前后缀、[a][b](u));该会话全部 213 段text/result/command用新正则一趟跑完,0 停滞。npm --prefix web run build(tsc --noEmit + vite build)通过。Merge Danger
Door: two-way
Blast Radius: markdown
改的是纯正则 + 一条注释,回滚就是一个 revert;没有数据、协议或磁盘格式变化。唯一风险是「本来不该被认成链接的方括号文本现在被认成链接」——Kleene 闭包同语言,逐字匹配掉的只是切分歧义,13 组等价性案例里没有差异。
顺带记录:
D95在 main 的决策日志里是空号(D94 之后直接没有),这篇占这个位置,docs/DECISIONS.md里那一节写了「为什么」和实测阈值。