web: sanitizer strips MathML <annotation>/<semantics> from rendered KaTeX — LaTeX source missing from DOM (copy-to-LaTeX tools broken)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 77/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- frontend
調査の方向性
packages/session-ui/src/components/markdown-cache.tsxを読み、サニタイザー設定のADD_TAGSリストを調べてください。そこでMathML出力がサニタイズされることを確認し、変更後もannotationとそのTeXソースがDOMに残ることを確認してください。annotationベースのコピー用ツールがソースを読み取れ、レンダリングされた数式も引き続き正しく表示されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
In the web UI, rendered math looks correct, but the LaTeX source is absent from the DOM. KaTeX produces its default output (htmlAndMathml, i.e. HTML + MathML with <semantics><annotation encoding="application/x-tex">), but the HTML is passed through sanitizeMarkdown() before insertion, and the sanitizer's mathMl profile strips <semantics> / <annotation>. Consequences:
- Browser extensions / userscripts that copy the original TeX (the KaTeX
contrib/copy-texecosystem: "Copy LaTeX", "Formula Copy", etc.) cannot work on the web UI, while they work on katex.org / other chat UIs. - MathML semantics are lost for assistive technology and other DOM consumers.
Tested on OpenCode v2.0.25 (web UI, Chrome; served bundle _assets/markdown.worker-*.js contains marked + KaTeX 0.16.47). The same config is still present in dev.
Steps to reproduce
-
Open the web UI, ask the model for a display formula, e.g.:
$$ \begin{aligned} (a+b)^3 &= (a+b)(a+b)^2 \\ &= a^3 + 3a^2 b + 3ab^2 + b^3 . \end{aligned} $$ -
With the formulas rendered, run in DevTools console:
document.querySelectorAll(".katex").length // > 0 — math is rendered document.querySelectorAll('annotation[encoding="application/x-tex"]').length // 0 — but the LaTeX source is not in the DOM -
Or install any annotation-based copy extension (e.g. "Copy LaTeX (KaTeX & MathJax)"): it does nothing on OpenCode, while working on katex.org.
Expected
The DOM should retain KaTeX's MathML output, including <annotation encoding="application/x-tex"> with the original TeX (KaTeX's default behavior; what other AI chat UIs expose).
Actual
<semantics> and <annotation> are removed by sanitization. Visual rendering is unaffected (the HTML part is kept), so the loss is invisible until you try to copy a formula's source.
Root cause
-
packages/session-ui/src/components/markdown-cache.tsx:const config = { USE_PROFILES: { html: true, mathMl: true }, SANITIZE_NAMED_PROPS: true, FORBID_TAGS: ["style"], FORBID_CONTENTS: ["style", "script"], ADD_TAGS: ["svg", "path"], ADD_ATTR: ["d", "viewBox", "preserveAspectRatio", "xmlns", "target"], } -
DOMPurify's built-in
mathMlprofile allowlist does not includesemantics/annotation/annotation-xml, so the MathML annotation (and itsencodingattribute) is dropped.
Suggested fix
Extend the allowlist (verified locally with the exact config above on doMPurify 3.4.16 — the annotation then survives sanitization and is queryable in the DOM):
- ADD_TAGS: ["svg", "path"],
+ ADD_TAGS: ["svg", "path", "semantics", "annotation", "annotation-xml"],
No ADD_ATTR change is needed (encoding is already in DOMPurify's MathML attribute allowlist). The elements are plain text containers; allowing them carries no scripting risk.
Local verification (before/after)
- Worker output: contains
application/x-tex✓ - After
sanitizeMarkdownconfig:annotationcount = 0 - After adding the three tags:
annotationcount = 1,<annotation encoding="application/x-tex">…</annotation>intact
- 主要言語
- TypeScript
- スター
- 213k
- フォーク
- 28.4k
- 平均マージ
- 8時間 32分
- マージ済み PR(30日)
- 253
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
anomalyco/opencode のほかの issue
-
app: keybinds match the produced character, so Ctrl+F and other letter shortcuts fail on non-Latin layouts対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンreproduced
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
anomalyco/opencode#55676 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
tui: NumPad End/Home ignored under kitty keyboard protocol (Windows Terminal reports KP_END 57424)対応中かも @argszero が 1 日前に担当しました。 オープンreproduced
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
anomalyco/opencode#55533 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
pending close triaging
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
anomalyco/opencode#55392 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
anomalyco/opencode#55383 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
web: second Firefox tab never connects to /api/event - Cache-Control: no-cache lets Firefox's HTTP cache block concurrent SSE requests対応中かも @zonemeen が 1 日前に担当しました。 オープンreproduced
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
anomalyco/opencode#55369 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
anomalyco/opencode の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
QuantumNous/new-api#7839 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
bug p2 triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
getpaseo/paseo#7071 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
test: make the #3408 Claude OAuth token fixture obviously fake so secret scanners stop flagging itオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
code-yeongyu/senpi#3436 ·
メンテナーはふだん 1 日以内に返信
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
lingdojo/kana-dojo#32505 · コメント 1 件 · リアクション 5 件 ·
メンテナーはふだん 1 日以内に返信