mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
fix(shell): preserve UTF-8 native input on PowerShell 5 (#5160)
Windows PowerShell 5.1 defaults $OutputEncoding to US-ASCII, corrupting non-ASCII strings piped to native commands. Set it from the console encoding only on legacy versions so PowerShell 7 keeps its defaults.
This commit is contained in:
parent
757ad9c764
commit
5a28a6165c
@ -556,6 +556,7 @@ class ExecTool(Tool):
|
|||||||
command = ExecTool._normalize_powershell_command(command)
|
command = ExecTool._normalize_powershell_command(command)
|
||||||
command = (
|
command = (
|
||||||
"[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)\n"
|
"[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)\n"
|
||||||
|
"if ($PSVersionTable.PSVersion.Major -lt 6) { $OutputEncoding = [Console]::OutputEncoding }\n"
|
||||||
"$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'\n"
|
"$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'\n"
|
||||||
f"{command}\n"
|
f"{command}\n"
|
||||||
"if ($LASTEXITCODE -ne $null) { exit $LASTEXITCODE }"
|
"if ($LASTEXITCODE -ne $null) { exit $LASTEXITCODE }"
|
||||||
|
|||||||
@ -230,8 +230,8 @@ class TestSpawnWindows:
|
|||||||
assert "if ($LASTEXITCODE -ne $null) { exit $LASTEXITCODE }" in command
|
assert "if ($LASTEXITCODE -ne $null) { exit $LASTEXITCODE }" in command
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_powershell_configures_utf8_output(self):
|
async def test_powershell_configures_utf8_io(self):
|
||||||
"""PowerShell should emit UTF-8 for captured output and redirections."""
|
"""PowerShell should use UTF-8 for captured output, native input, and redirections."""
|
||||||
env = {"PATH": ""}
|
env = {"PATH": ""}
|
||||||
with (
|
with (
|
||||||
patch("nanobot.agent.tools.shell._IS_WINDOWS", True),
|
patch("nanobot.agent.tools.shell._IS_WINDOWS", True),
|
||||||
@ -242,7 +242,10 @@ class TestSpawnWindows:
|
|||||||
|
|
||||||
command = mock_exec.call_args[0][-1]
|
command = mock_exec.call_args[0][-1]
|
||||||
assert "[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)" in command
|
assert "[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)" in command
|
||||||
assert "$OutputEncoding =" not in command
|
assert (
|
||||||
|
"if ($PSVersionTable.PSVersion.Major -lt 6) { "
|
||||||
|
"$OutputEncoding = [Console]::OutputEncoding }"
|
||||||
|
) in command
|
||||||
assert "$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'" in command
|
assert "$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'" in command
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@ -821,6 +824,20 @@ class TestWindowsRealExec:
|
|||||||
assert b"\x00" not in data
|
assert b"\x00" not in data
|
||||||
assert data.decode("utf-8-sig").strip() == "file café λ 你好"
|
assert data.decode("utf-8-sig").strip() == "file café λ 你好"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_windows_powershell_native_pipeline_input_is_utf8(self):
|
||||||
|
python = sys.executable.replace("'", "''")
|
||||||
|
result = await ExecTool(timeout=180).execute(
|
||||||
|
command=(
|
||||||
|
f"[string][char]0x4F1A | & '{python}' "
|
||||||
|
'-c "import sys; print(sys.stdin.buffer.read().hex())"'
|
||||||
|
),
|
||||||
|
shell="powershell",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert "e4bc9a0d0a" in result
|
||||||
|
assert "Exit code: 0" in result
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_windows_powershell_session_output_is_utf8(self):
|
async def test_windows_powershell_session_output_is_utf8(self):
|
||||||
manager = ExecSessionManager()
|
manager = ExecSessionManager()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user