sjr666666 19e0242476
fix(sandbox): decode cmd.exe output with the ANSI code page under UTF-8 mode (#6777)
* fix(sandbox): decode cmd.exe output with the ANSI code page under UTF-8 mode

The cmd.exe branch left its pipe decoder to the `encoding=None` default of
`_run_windows_command`, which follows Python text-mode semantics via
`locale.getpreferredencoding(False)`. Under Python UTF-8 mode
(`PYTHONUTF8=1`, `-X utf8`, the Windows installer's UTF-8 opt-in, and the
default once PEP 686 lands) that call reports `"utf-8"`, while cmd.exe and
the children it spawns keep writing the host ANSI code page - so every
non-ASCII byte in cmd output collapses to U+FFFD, with no fallback path.

Measured on a real zh-CN host under `PYTHONUTF8=1` (`getpreferredencoding`
-> `utf-8`, `getencoding` -> `cp936`):

- through the `encoding=None` default: `'��� �����Z
'`
- pinned to the ANSI code page: `'你好 日本語
'`

This branch pins the cmd.exe pipe decoder to `locale.getencoding()`
(3.11+, repo floor is 3.12), the same selection the MSYS and PowerShell
branches already use for their fallback (#6727, #6548).

## Scope note

The `encoding=None` default itself is deliberately unchanged: it mirrors
Python's own `text=True` semantics and is pinned by
`test_windows_capture_matches_subprocess_text_mode_encoding`. Only the
cmd.exe branch - whose output is known to be the ANSI code page - overrides
it, the same way the MSYS and PowerShell branches already pin their own
decoders.

Follow-up to willem-bd's review note on #6727 (inline comment 4247281255)
flagging this path.

## Testing

- new (POSIX-runnable, mocked): the cmd branch passes
  `encoding=locale.getencoding()` to `_run_windows_command`, verified under
  a simulated UTF-8-mode host (`getpreferredencoding` -> `utf-8`,
  `getencoding` -> `cp936`).
- updated: `test_execute_command_uses_cmd_command_mode_on_windows` now also
  pins the new `encoding` kwarg.
- new (Windows; skipped when the console output CP does not match the ANSI
  page - sibling tests can change it process-wide): real `cmd.exe /c echo`
  roundtrip through `execute_command` returns the text intact (passes on a
  zh-CN host when run standalone).
- full `tests/test_local_sandbox_encoding.py`: 40 passed, 2 skipped under
  both `PYTHONUTF8=0` and `PYTHONUTF8=1` (Windows 11, Python 3.13.12, repo
  venv); the text-mode contract test stays green in all three parametrized
  modes (`locale-code-page`, `PYTHONUTF8`, `-X-utf8`). Red run against
  unmodified main: both new/updated cmd-branch tests fail (`KeyError:
  'encoding'`).
- `ruff check` + `ruff format --check` clean on both files.

* fix(sandbox): use the cmd console output code page

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-10-13 14:27:26 +08:00
..