fix: chunk multiline PTY writes on macOS to avoid 1024-byte buffer corruption#298993
Open
jcansdale wants to merge 2 commits intomicrosoft:mainfrom
Open
fix: chunk multiline PTY writes on macOS to avoid 1024-byte buffer corruption#298993jcansdale wants to merge 2 commits intomicrosoft:mainfrom
jcansdale wants to merge 2 commits intomicrosoft:mainfrom
Conversation
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
Contributor
There was a problem hiding this comment.
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.
c21ed81 to
a09dc3f
Compare
…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
a09dc3f to
0fd94f3
Compare
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: @TyriarMatched files:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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, longgit commitmessages, etc.Evidence
The first commit adds a test (without the fix) that failed on macOS CI, reproducing the exact corruption pattern:
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.Changed files
src/vs/platform/terminal/node/terminalProcess.ts—_writeChunked()method + chunking branch ininput()src/vs/platform/terminal/test/node/terminalProcess.test.ts(new) — integration tests spawning real PTY processes with 10/20/30-line multiline commandsSee also: https://github.com/jcansdale/macos-pty-multiline-bug (standalone reproducers confirming this is a macOS kernel-level issue)