Skip to content

fix: drop regex lookbehind in GFM autolink to fix legacy-WebKit white screen - #27

Merged
shaohaozhi286 merged 2 commits into
masterfrom
bugfix/webkit-lookbehind-autolink
Aug 31, 2026
Merged

shaohaozhi286 merged 2 commits into
masterfrom
bugfix/webkit-lookbehind-autolink

Conversation

@LIUXIN557

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: The embedded frontend bundle used a regex lookbehind assertion (?<=...) (from mdast-util-gfm-autolink-literal@2.0.1's email autolink pattern). Lookbehind requires Safari 16.4+, but on macOS 12 the WKWebView / JavaScriptCore engine is pinned to Safari 15.6. The whole bundle failed to parse at load time, React never mounted, and the desktop main window rendered a white screen. Chrome (much newer engine) rendered normally, confirming the engine-version gap.
  • Fix: Removed the lookbehind assertion via a pnpm patch on mdast-util-gfm-autolink-literal@2.0.1. The findEmail callback already runs a runtime previous(match, true) check that validates the preceding character, so dropping the lookbehind keeps valid email autolinking identical while letting the bundle compile on Safari 15.6-class engines.
  • Regression guard: Added web/src/lib/gfmAutolinkCompat.test.js (7 cases) and web/scripts/check-regex-compat.mjs, wired into pnpm build to fail the build if any dist regex literal still uses lookbehind.
  • Build prerequisite: src/desktop/agent_browser_host_mac.mm had 10 LOG_* macro calls whose braced json{...} argument was being split on commas. Parenthesized the argument so the macOS desktop target compiles. (Required to actually ship the rebuilt desktop app on macOS.)

Test plan

  • pnpm install && pnpm build in web/ — passes the regex-compat check.
  • System JSC new Function(bundle) syntax check passes on macOS 12 (no Invalid regular expression).
  • Verified end-to-end on the user's macOS 12 machine: rebuilt desktop app renders; delivered bundle contains no lookbehind.

Impact / follow-ups

  • Functionality risk: low — email autolink behavior preserved by the existing runtime preceding-char check.
  • Maintenance: the pnpm patch must be re-validated (or removed) when mdast-util-gfm-autolink-literal is upgraded past the lookbehind usage.

mdast-util-gfm-autolink-literal@2.0.1 uses a lookbehind assertion in its
email autolink regex. Legacy WebKit engines (Safari < 16.4, e.g. the
WKWebView on macOS 12) cannot compile lookbehind, and since regex
literals compile at module parse time the whole frontend bundle failed
to parse, rendering a blank screen in ACECode desktop.

Patch the dependency to remove the lookbehind: findEmail already
re-validates the preceding character at runtime via previous(match,
true), so behavior is unchanged (covered by new regression tests).

Also add scripts/check-regex-compat.mjs to the build so any future
lookbehind regex literal in the bundle fails the build instead of
blank-screening legacy WebKit users at runtime.
@LIUXIN557
LIUXIN557 force-pushed the bugfix/webkit-lookbehind-autolink branch from ae4cccc to ce3f902 Compare August 30, 2026 16:02

@shaohaozhi286 shaohaozhi286 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

批准合入。

lookbehind 从 pnpm patch 去掉是对症的:legacy WebKit 在 parse 阶段就编译 regex literal,单条就能让整个 bundle 白屏。findEmail 里现有的 previous(match, true) 能接住前置字符校验,7 个 autolink 回归用例也覆盖了常见边界。

check-regex-compat.mjs 扫 dist/index.html 在这个仓库里是成立的:vite-plugin-singlefile 把 JS 全部 inline 进 html。pnpm build 后挂这个检查能挡住以后新的 lookbehind。

顺带:PR 描述里写了 agent_browser_host_mac.mm 的 LOG_* 括号修复,但这两个 commit 里没有这个文件。不影响本次修复。

@shaohaozhi286
shaohaozhi286 merged commit 5e52ec0 into master Aug 31, 2026
1 check passed
@shaohaozhi286
shaohaozhi286 deleted the bugfix/webkit-lookbehind-autolink branch August 31, 2026 17: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.

3 participants