Skip to content

fix(terminal,parser): accept OSC 52 payloads larger than 1 KiB - #102

Merged
roramirez merged 1 commit into
mainfrom
fix/osc52-large-payload
Aug 16, 2026
Merged

fix(terminal,parser): accept OSC 52 payloads larger than 1 KiB#102
roramirez merged 1 commit into
mainfrom
fix/osc52-large-payload

Conversation

@roramirez

Copy link
Copy Markdown
Owner

Summary

Copying from a program running over SSH silently did nothing when the text was longer than roughly 750 characters. The remote program sends the clipboard through OSC 52;c;<base64> ST, but mmterm dropped the sequence instead of writing to the host clipboard.

The cause is in the vte dependency: its default no_std feature stores the OSC payload in a fixed 1024-byte ArrayVec and stops accumulating once that buffer is full (Action::OscPut returns early when osc_raw.is_full()). A 981-character selection encodes to ~1308 bytes of base64, so the sequence arrived truncated, BASE64.decode failed, and pending_clipboard_write stayed None — no error, no clipboard update.

Turning the feature off swaps the fixed buffer for a growable Vec, which is what other terminals (Alacritty) do for the same reason. OSC 8 hyperlinks and every other OSC handler benefit from the same lift; nothing in mmterm depended on the 1 KiB cap.

Changes

  • Cargo.tomlvte = { version = "0.13", default-features = false }, with a comment recording why the default feature is off.
  • Cargo.lock — drops the now-unused arrayvec dependency.
  • CHANGELOG.md — entry under [Unreleased]Fixed.
  • src/terminal/parser_test.rsosc52_write_handles_payload_larger_than_1kb, a regression test built from the exact size that failed in practice (981 chars). It fails on main and passes with the fix.

Design notes: the fix is confined to the dependency's buffer strategy — osc_clipboard in src/terminal/parser.rs is unchanged, so the write/read/invalid-base64 behaviour and their existing tests stay as they were. The parser hot path is untouched; Vec growth only occurs while an OSC sequence is being accumulated.

How to test

Automated:

cargo fmt --check
cargo clippy --locked -- -D warnings
cargo test

New test: osc52_write_handles_payload_larger_than_1kb. Full suite: 1245 tests pass.

Manual (end-to-end):

  1. cargo run and SSH into another host from inside mmterm.
  2. Run a program there that copies via OSC 52 (Claude Code, nvim with an OSC 52 clipboard provider, or by hand: printf '\033]52;c;%s\a' "$(head -c 900 /dev/urandom | base64 -w0)").
  3. Paste into any local application — the full text arrives instead of nothing.
  4. Repeat with a short selection to confirm the sub-1 KiB path still works.

vte's default `no_std` feature stores the OSC buffer in a fixed 1024-byte
ArrayVec, so any OSC 52 clipboard write past that size was truncated and
its base64 failed to decode — copying long text over SSH silently did
nothing. Disabling the feature swaps the buffer for a growable Vec.
@roramirez
roramirez merged commit 449ce26 into main Aug 16, 2026
2 checks passed
@roramirez
roramirez deleted the fix/osc52-large-payload branch August 16, 2026 15:50
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.

1 participant