Skip to content

fix: chunk multiline PTY writes on macOS to avoid 1024-byte buffer corruption#298993

Open
jcansdale wants to merge 2 commits intomicrosoft:mainfrom
jcansdale:jcansdale/pty-multiline-test
Open

fix: chunk multiline PTY writes on macOS to avoid 1024-byte buffer corruption#298993
jcansdale wants to merge 2 commits intomicrosoft:mainfrom
jcansdale:jcansdale/pty-multiline-test

Conversation

@jcansdale
Copy link

@jcansdale jcansdale commented Mar 3, 2026

Fixes #296955

Problem

macOS PTY has a ~1024-byte canonical-mode input buffer. When multiline commands (containing CR/newline characters) exceed this threshold, the shell's line editor echoes characters back, creating backpressure that corrupts the write — data after ~1024 bytes wraps around and replays earlier buffer content, destroying the remainder of the command and leaving the shell stuck.

This affects any multiline terminal input over ~1KB: heredocs, gh issue create --body, inline Python/Node scripts, long git commit messages, etc.

Evidence

The first commit adds a test (without the fix) that failed on macOS CI, reproducing the exact corruption pattern:

+ L19 aaaaaaaaaaaaL19 aaaaaaaaaaaaL19 aaaaaaaaaaaaL19 aaaaaaaaaaa...
- L19 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- L20 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  ...lines L20-L30 lost entirely...

The test passed on Linux and Windows — only macOS is affected.

Fix

In TerminalProcess.input(), when on macOS and the data is multiline and exceeds 512 bytes, write in 512-byte chunks with 5ms pauses between them. This allows the shell's echo buffer to drain between chunks, preventing the backpressure deadlock.

  • Non-macOS platforms: unaffected (direct write as before)
  • Single-line commands: unaffected (no backpressure from line editor)
  • Binary writes: unaffected

Changed files

  • src/vs/platform/terminal/node/terminalProcess.ts_writeChunked() method + chunking branch in input()
  • src/vs/platform/terminal/test/node/terminalProcess.test.ts (new) — integration tests spawning real PTY processes with 10/20/30-line multiline commands

See also: https://github.com/jcansdale/macos-pty-multiline-bug (standalone reproducers confirming this is a macOS kernel-level issue)

Adds a test that sends multiline commands of varying sizes (10, 20, 30 lines)
through TerminalProcess.input() and verifies the data arrives intact at the
shell. On macOS, multiline commands exceeding ~1024 bytes corrupt due to PTY
canonical-mode input buffer backpressure.

Reproduces: microsoft#296955
Copilot AI review requested due to automatic review settings March 3, 2026 16:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new test file src/vs/platform/terminal/test/node/terminalProcess.test.ts to document and reproduce a macOS PTY bug where multiline commands exceeding approximately 1024 bytes get corrupted (issue #296955). The test spawns a real PTY process via TerminalProcess, sends a heredoc command of varying sizes through TerminalProcess.input(), and verifies the shell received the complete payload by checking the output file contents.

Changes:

  • Adds a new test file with 3 test cases (10-, 20-, and 30-line heredoc commands) to reproduce the PTY 1024-byte buffer bug on macOS/Linux.

@jcansdale jcansdale changed the title test: add multiline PTY write test for macOS 1024-byte buffer bug fix: chunk multiline PTY writes on macOS to avoid 1024-byte buffer corruption Mar 3, 2026
@jcansdale jcansdale force-pushed the jcansdale/pty-multiline-test branch 4 times, most recently from c21ed81 to a09dc3f Compare March 3, 2026 17:12
…rruption

macOS PTY has a ~1024-byte canonical-mode input buffer. When multiline data
(containing CR characters) exceeds this threshold, the shell's line editor
echoes characters back, creating backpressure that corrupts the write.

Write multiline PTY input in 512-byte chunks with 5ms pauses between them
to allow the echo buffer to drain. Non-macOS platforms and single-line
writes are unaffected.

Fixes microsoft#296955
@jcansdale jcansdale force-pushed the jcansdale/pty-multiline-test branch from a09dc3f to 0fd94f3 Compare March 3, 2026 18:01
@jcansdale jcansdale marked this pull request as ready for review March 3, 2026 19:10
@vs-code-engineering
Copy link

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@Tyriar

Matched files:

  • src/vs/platform/terminal/node/terminalProcess.ts

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.

Terminal tool corrupts multiline commands exceeding 1024 bytes

4 participants