Skip to content

Commit

Permalink
WinRM/PSRP: Ensure shell returns UTF-8 output (ansible#47404)
Browse files Browse the repository at this point in the history
* WinRM/PSRP: Ensure shell returns UTF-8 output

This PR makes UTF-8 output work in PSRP shells.

* Add win_command and win_shell integration tests

* Fix tests

* more test fixes
  • Loading branch information
dagwieers authored and Tomorrow9 committed Dec 4, 2018
1 parent badf770 commit 10c78a3
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/psrp-utf8-stdio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- psrp - Fix UTF-8 output - https://github.com/ansible/ansible/pull/46998
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,23 @@ namespace Ansible
StringBuilder lpBuffer,
out IntPtr lpFilePart);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleCP(
UInt32 wCodePageID);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleOutputCP(
UInt32 wCodePageID);
[DllImport("shell32.dll", SetLastError = true)]
static extern IntPtr CommandLineToArgvW(
[MarshalAs(UnmanagedType.LPWStr)]
Expand Down Expand Up @@ -252,6 +269,16 @@ namespace Ansible
if (environmentString != null)
lpEnvironment = Marshal.StringToHGlobalUni(environmentString.ToString());
// Create console if needed to be inherited by child process
bool isConsole = false;
if (GetConsoleWindow() == IntPtr.Zero) {
isConsole = AllocConsole();
// Set console input/output codepage to UTF-8
SetConsoleCP(65001);
SetConsoleOutputCP(65001);
}
// Create new process and run
StringBuilder argument_string = new StringBuilder(lpCommandLine);
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
Expand All @@ -270,6 +297,11 @@ namespace Ansible
throw new Win32Exception("Failed to create new process");
}
// Destroy console if we created it
if (isConsole) {
FreeConsole();
}
// Setup the output buffers and get stdout/stderr
FileStream stdout_fs = new FileStream(stdout_read, FileAccess.Read, 4096);
StreamReader stdout = new StreamReader(stdout_fs, utf8_encoding, true, 4096);
Expand Down
24 changes: 24 additions & 0 deletions test/integration/targets/connection_psrp/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,27 @@
assert:
that:
- async_out.stdout_lines == ["abc"]

- name: Output unicode characters from Powershell using PSRP
win_command: "powershell.exe -ExecutionPolicy ByPass -Command \"Write-Host '\U0001F4A9'\""
register: command_unicode_output

- name: Assert unicode output
assert:
that:
- command_unicode_output is changed
- command_unicode_output.rc == 0
- "command_unicode_output.stdout == '\U0001F4A9\n'"
- command_unicode_output.stderr == ''

- name: Output unicode characters from Powershell using PSRP
win_shell: "Write-Host '\U0001F4A9'"
register: shell_unicode_output

- name: Assert unicode output
assert:
that:
- shell_unicode_output is changed
- shell_unicode_output.rc == 0
- "shell_unicode_output.stdout == '\U0001F4A9\n'"
- shell_unicode_output.stderr == ''
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ Assert-Equals -actual $actual.rc -expected 0
Assert-Equals -actual $actual.stdout -expected "stdout `r`n"
Assert-Equals -actual $actual.stderr -expected "stderr `r`n"

$test_name = "Test UTF8 output from stdout stream"
$actual = Run-Command -command "powershell.exe -ExecutionPolicy ByPass -Command `"Write-Host '💩'`""
Assert-Equals -actual $actual.rc -expected 0
Assert-Equals -actual $actual.stdout -expected "💩`n"
Assert-Equals -actual $actual.stderr -expected ""

$test_name = "test default environment variable"
Set-Item -Path env:TESTENV -Value "test"
$actual = Run-Command -command "cmd.exe /c set"
Expand Down

0 comments on commit 10c78a3

Please sign in to comment.