Skip to content

fix(dev-mcp): pin UTF-8 for PowerShell shell commands - #7096

Open
PresentJay wants to merge 1 commit into
block:mainfrom
PresentJay:fix/powershell-utf8-pipe
Open

fix(dev-mcp): pin UTF-8 for PowerShell shell commands#7096
PresentJay wants to merge 1 commit into
block:mainfrom
PresentJay:fix/powershell-utf8-pipe

Conversation

@PresentJay

Copy link
Copy Markdown

Windows PowerShell 5.1 encodes what it writes to a native process with the legacy console codepage and substitutes ? for every character that codepage cannot represent. Prose piped into buzz messages send --content - loses its em dashes, curly quotes, and non-Latin text before the event is built and signed — and the command still exits 0, so the corruption is silent and permanent in message history.

buzz-dev-mcp spawns that shell for every dev__shell call, which is the path managed agents use to reach the CLI. This pins BOM-less UTF-8 on the session before the caller's command runs:

$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(); <command>

That is the workaround from the issue, moved from the caller into the spawn so it holds for every session. A prompt-level instruction cannot: each channel is an independent, long-running agent session, so one can comply while another keeps using the legacy encoding.

Dispatch is on the resolved shell (powershell / pwsh), not the host OS, matching how shell_flag right above it already picks the command flag. Every other shell is handed the command unchanged.

Fixes #6527

Test

Two cases in crates/buzz-dev-mcp/src/shell.rs, over the command string that is actually handed to the shell:

  • powershell_command_pins_utf8_before_the_callers_command — asserts the preamble comes first and the caller's command (em dash — café 測試 🐝) survives intact, for powershell.exe, pwsh.exe, and pwsh. Before the change it fails with the command returned bare.
  • other_shells_receive_the_command_unchangedbash, /bin/zsh, sh, and cmd.exe are untouched.
cargo test -p buzz-dev-mcp   101 passed / 0 failed
just fmt-check               clean
just clippy                  clean
just test-unit               9/9 lanes pass

Scope note: this covers how the command is constructed. The end-to-end Windows assertion the issue asks for — sending through a live harness and reading the accepted event's code points back — is not included here; it needs a Windows runner this change cannot provide.

Windows PowerShell 5.1 encodes what it writes to a native process with
the legacy console codepage and substitutes `?` for every character that
codepage cannot represent. Prose piped into `buzz messages send
--content -` loses its em dashes, curly quotes, and non-Latin text before
the event is built and signed, and the command still reports success — so
the corruption is silent and permanent in message history.

Prepend the UTF-8 pin to the command string when the resolved shell is
powershell or pwsh, so it holds for every session rather than depending
on each caller setting `$OutputEncoding` first. Other shells are handed
the command unchanged.

Fixes block#6527

Signed-off-by: Hyeonjae.Jeong <presentj94@gmail.com>
@PresentJay
PresentJay requested a review from a team as a code owner August 31, 2026 07:00
@github-actions

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is c3132c3ee982d194cd0198ad07b57ec8bd726e4e...a71fba71abeb9d21cf69d6b2f5ba0dff3e69abc0.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review a71fba71abeb9d21cf69d6b2f5ba0dff3e69abc0 to authorize a new review.
Any previous review applies only to its recorded range.

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.

Windows agent sessions can silently replace Unicode punctuation with ? before signing messages

1 participant