From d9f53128b7ab0a0d9b0b079a6ce0268b87263039 Mon Sep 17 00:00:00 2001 From: iceweasel-oai Date: Thu, 28 May 2026 13:58:20 -0700 Subject: [PATCH] [codex] Handle PowerShell UTF-8 setup failures (#24949) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #12496. ## Why Windows sandboxed PowerShell commands can run under `ConstrainedLanguage` on some machines, especially enterprise-managed Windows environments. In that mode, our PowerShell command prelude could fail before every command because it directly assigned `[Console]::OutputEncoding` to UTF-8. The actual user command still ran, but Codex surfaced noisy `Cannot set property. Property setting is supported only on core types in this language mode.` output for every shell call. ## What Changed - Makes the PowerShell UTF-8 output encoding prelude best-effort by wrapping the assignment in `try { ... } catch {}`. - Keeps the existing UTF-8 behavior when PowerShell allows the assignment. - Adds focused tests for adding the prelude and avoiding duplicate prelude insertion. ## Validation - `cargo fmt -p codex-shell-command` - `cargo check -p codex-shell-command` - `git diff --check` - Verified a local `ConstrainedLanguage` PowerShell probe prints only the command output with no property-setting error. - Verified `codex exec` from a temporary `chcp 437` context reports `utf-8` / `65001` and preserves non-ASCII output (`café`, `漢字`). --- codex-rs/shell-command/src/powershell.rs | 38 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/codex-rs/shell-command/src/powershell.rs b/codex-rs/shell-command/src/powershell.rs index f7b294c0f..e8c9a500c 100644 --- a/codex-rs/shell-command/src/powershell.rs +++ b/codex-rs/shell-command/src/powershell.rs @@ -8,8 +8,9 @@ use crate::shell_detect::detect_shell_type; const POWERSHELL_FLAGS: &[&str] = &["-nologo", "-noprofile", "-command", "-c"]; -/// Prefixed command for powershell shell calls to force UTF-8 console output. -pub const UTF8_OUTPUT_PREFIX: &str = "[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;\n"; +/// Prefixed command for powershell shell calls to request UTF-8 console output. +pub const UTF8_OUTPUT_PREFIX: &str = + "try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\n"; pub fn prefix_powershell_script_with_utf8(command: &[String]) -> Vec { let Some((_, script)) = extract_powershell_command(command) else { @@ -151,9 +152,11 @@ fn is_powershellish_executable_available(powershell_or_pwsh_exe: &std::path::Pat #[cfg(test)] mod tests { + use super::UTF8_OUTPUT_PREFIX; use super::extract_powershell_command; #[cfg(windows)] use super::parse_powershell_command_into_plain_commands; + use super::prefix_powershell_script_with_utf8; #[test] fn extracts_basic_powershell_command() { @@ -202,6 +205,37 @@ mod tests { assert_eq!(script, "Get-ChildItem | Select-String foo"); } + #[test] + fn prefixes_powershell_command_with_best_effort_utf8() { + let cmd = vec![ + "powershell".to_string(), + "-Command".to_string(), + "Write-Host hi".to_string(), + ]; + + let prefixed = prefix_powershell_script_with_utf8(&cmd); + + assert_eq!( + prefixed, + vec![ + "powershell".to_string(), + "-Command".to_string(), + format!("{UTF8_OUTPUT_PREFIX}Write-Host hi"), + ] + ); + } + + #[test] + fn does_not_duplicate_utf8_prefix() { + let cmd = vec![ + "powershell".to_string(), + "-Command".to_string(), + format!("{UTF8_OUTPUT_PREFIX}Write-Host hi"), + ]; + + assert_eq!(prefix_powershell_script_with_utf8(&cmd), cmd); + } + #[cfg(windows)] #[test] fn parses_plain_powershell_commands() {