WASM memory corruption after freeing terminal that processed multi-codepoint grapheme clusters
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- typescript, wasm
調査の方向性
まず Bun で repro.ts を実行し、次に terminal.free と ghostty-web.js:145 に示されている ghostty_terminal_write の呼び出しを調べます。単一のコードポイントのテキストの後にターミナルを解放する場合と、列挙されたグラフェムクラスタの後にターミナルを解放する場合を比較します。その後の createTerminal() および write() の呼び出しで境界外メモリアクセスが発生しなくなれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Environment
- OS: macOS 15.4 (Darwin 25.2.0, arm64)
- Package: ghostty-web@0.4.0
- Runtime: Bun 1.3.9
Description
Calling terminal.free() after writing any multi-codepoint grapheme cluster (flag emoji, skin tone modifiers, ZWJ sequences, keycap sequences) corrupts the shared WASM memory. All subsequent createTerminal() + write() calls crash with an out-of-bounds memory access.
Single-codepoint characters (ASCII, CJK, simple emoji like 😀) do not trigger the bug.
Reproduction
import { Ghostty } from "ghostty-web";
const ghostty = await Ghostty.load();
const term1 = ghostty.createTerminal(80, 24);
term1.write("👋🏽"); // Any multi-codepoint grapheme cluster
term1.free(); // ← corrupts WASM memory
const term2 = ghostty.createTerminal(80, 24);
term2.write("Hello"); // ← crashes
Save as repro.ts and run with bun run repro.ts.
Characters that trigger the bug
All multi-codepoint grapheme clusters:
- Flag emoji: 🇺🇸 🇬🇧 🇯🇵 (regional indicator pairs)
- Skin tone: 👋🏽 (base + Fitzpatrick modifier)
- ZWJ families: 👨👩👧 (ZWJ sequences)
- Keycap: 1️⃣ (digit + VS16 + combining enclosing keycap)
Characters that do NOT trigger the bug
Single-codepoint characters:
- ASCII:
Hello - CJK:
漢字 - Simple emoji:
😀(single codepoint, no modifiers)
Error Output
RuntimeError: Out of bounds memory access (evaluating 'this.exports.ghostty_terminal_write(this.handle, g, B.length)')
at write (ghostty-web.js:145:64)
The crash is in ghostty_terminal_write — the WASM linear memory has been corrupted by the preceding free(), so the next write() accesses invalid memory.
Impact
This blocks using ghostty-web for multi-terminal workflows (test suites, terminal pools, tab management) where terminals are created, used, and freed in sequence. If any terminal processes grapheme clusters before being freed, all subsequent terminals in the same WASM instance are broken.
Workaround
Don't free terminals that have processed multi-codepoint grapheme clusters. Leak them instead:
// Instead of term.free(), just abandon the reference
// term.free() // ← skip this
term = null;
Or use one process per terminal (expensive but avoids shared WASM state).
- 主要言語
- TypeScript
- スター
- 2.9k
- フォーク
- 174
- PR マージ指標
- 30日以内にマージされた PR はありません
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
coder/ghostty-web のほかの issue
-
attachCustomKeyEventHandler inverts xterm.js's return-value contract (silently swallows all input) オープン
難易度 3/5 1〜2日 初心者へのやさしさ 52/100
coder/ghostty-web#192 ·
-
A single throw inside render() permanently stops the render loop, and a consumer cannot restart it オープン
難易度 4/5 3〜5日 初心者へのやさしさ 65/100
coder/ghostty-web#189 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 70/100
coder/ghostty-web#188 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 45/100
coder/ghostty-web#187 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
coder/ghostty-web#186 · コメント 1 件 ·
coder/ghostty-web の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
bcgov/bc-wallet-mobile#4761 · コメント 1 件 ·
-
external-issue to-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
area-deployment area-integrations triage:bot-seen
難易度 2/5 半日 初心者へのやさしさ 86/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
refactor
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100