Skip to content

FIX: Make CLI/output encoding safe on Windows consoles#2213

Merged
romanlutz merged 1 commit into
microsoft:mainfrom
romanlutz:romanlutz-split-b-windows-encoding
Jul 17, 2026
Merged

FIX: Make CLI/output encoding safe on Windows consoles#2213
romanlutz merged 1 commit into
microsoft:mainfrom
romanlutz:romanlutz-split-b-windows-encoding

Conversation

@romanlutz

Copy link
Copy Markdown
Contributor

Description

Running the scanner CLI and output sinks on a limited Windows console (for example a cp1252 or plain ASCII code page) can crash with UnicodeEncodeError when non-ASCII text reaches stdout. Two spots are affected: the scenario run progress bar renders with Unicode block characters, and StdoutSink can be handed arbitrary Unicode from scenario output.

This change makes both paths degrade gracefully instead of crashing:

  • pyrit/cli/_output.py: before emitting the progress bar, probe whether the Unicode bar encodes under the current sys.stdout.encoding. If it does not (LookupError or UnicodeEncodeError), fall back to an ASCII bar using # and -.
  • pyrit/output/sink.py: StdoutSink.write_async now checks whether the data is representable in the console encoding and, if not, writes it back through errors="replace" so unencodable characters become a placeholder rather than raising. This also switches from print to sys.stdout.write.

Both fallbacks are no-ops on UTF-8 consoles, so normal output is unchanged.

Tests and Documentation

Added focused unit tests:

  • test_print_scenario_run_progress_uses_ascii_for_limited_console - with a cp1252 stdout, asserts the progress bar renders the ASCII [###...---] form.
  • test_stdout_sink_replaces_unsupported_unicode - with a cp1252 stdout, asserts an emoji plus box-drawing dash is written as a replacement placeholder rather than raising.

Targeted unit runs pass: tests/unit/cli/test_output.py and tests/unit/output/test_sink.py (50 passed). The behavior was additionally verified end to end against a real cp1252 errors="strict" stdout wrapper, confirming the pre-patch UnicodeEncodeError, the ASCII progress-bar fallback, and the errors="replace" sink behavior, with plain ASCII output passing through untouched.

JupyText note: the related scanner notebooks (doc/scanner/1_pyrit_scan.py, doc/scanner/benchmark.py) were not executed as part of this validation because of a pre-existing local environment issue unrelated to this change (a stale ~/.pyrit/.pyrit_conf referencing a removed airt initializer prevents the backend from starting, and an ipykernel/IPython combination is incompatible with the local Python 3.14 kernel). Neither is caused by this diff.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 52d2518d-ebe5-4888-8189-6146b6503448
@romanlutz
romanlutz added this pull request to the merge queue Jul 17, 2026
Merged via the queue into microsoft:main with commit 96796c6 Jul 17, 2026
53 checks passed
@romanlutz
romanlutz deleted the romanlutz-split-b-windows-encoding branch July 17, 2026 14:24
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.

3 participants