Commit Graph
1 Commits
Author SHA1 Message Date
roboomp 089db21333 fix(tui): bound terminal input parsing so malformed sequences and non-bracketed pastes do not block the event loop
Three failure modes shared the same root cause on the StdinBuffer.process
hot path — unbounded synchronous work in a single call.

- `StdinBuffer.extractCompleteSequences` grew each escape candidate one code
  unit at a time and re-tested every prefix, so a malformed CSI/OSC/DCS/APC
  streamed across chunks re-inspected the accumulated buffer on every
  `process()` call (issue A). Replaced the grow-and-recheck loop with a
  single linear scan bounded by a per-type cap (CSI 4 KiB, OSC/DCS/APC 16
  MiB) and a resume-search offset carried on `StdinBuffer` so a legit
  chunked OSC 5522 image paste stays O(total) instead of O(total²).
- `BracketedPasteHandler` had no cap or timeout: a caller that bypassed
  StdinBuffer (fed the start marker with no end marker) grew `#buffer`
  forever (issue B, defense in depth). Added an optional `byteLimit` option
  (default 64 MiB) that aborts paste mode and delivers accumulated bytes as
  `pasteContent`, mirroring `StdinBuffer#abortPaste`.
- The `ProcessTerminal` data handler ran six always-executed escape-probe
  regex tests per `data` event; a 100 KB non-bracketed paste (terminal
  without DEC 2004 support) turned into ~600K regex executions (issue C).
  Added a fast path that forwards non-ESC sequences straight to the input
  handler when no reassembly buffer is holding state.

Verified with new stdin-buffer + bracketed-paste tests plus empirical
repros: a streamed 1 MiB malformed CSI drops from ~4300 ms to ~50 ms of
synchronous work, and a 1 MiB chunked OSC 5522 payload drops from ~6800 ms
to ~25 ms.

Fixes #4073
2026-07-01 07:19:28 +00:00