fix(windows): force console codepage to UTF-8 for shell/system() #38742

Problem:
On Windows, `:!echo тест` shows `????` because the console code page defaults to a legacy ANSI encoding (e.g. CP1252) instead of `UTF-8`

Solution:
Call `SetConsoleOutputCP(CP_UTF8)` and `SetConsoleCP(CP_UTF8)` in `do_os_system()` before spawning child processes, and restore the original values after. It covers both `:!` and `system()` since they both go through `do_os_system()`

(cherry picked from commit bba48ee1b0)
This commit is contained in:
Elijah Koulaxis
2026-04-06 02:16:48 +03:00
committed by github-actions[bot]
parent c692e848e9
commit d660233edf
2 changed files with 13 additions and 0 deletions

View File

@@ -867,6 +867,12 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
// environment variable $NoDefaultCurrentDirectoryInExePath
char *oldval = os_getenv("NoDefaultCurrentDirectoryInExePath");
os_setenv("NoDefaultCurrentDirectoryInExePath", "1", true);
UINT old_output_cp = GetConsoleOutputCP();
UINT old_input_cp = GetConsoleCP();
// Force console codepage to UTF-8 before spawning child process. #33480
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
#endif
out_data_decide_throttle(0); // Initialize throttle decider.
@@ -982,6 +988,8 @@ end:
#ifdef MSWIN
// Restore original value of NoDefaultCurrentDirectoryInExePath
restore_env_var("NoDefaultCurrentDirectoryInExePath", oldval, true);
SetConsoleOutputCP(old_output_cp);
SetConsoleCP(old_input_cp);
#endif
return exitcode;

View File

@@ -166,6 +166,11 @@ describe('system()', function()
test_shell_unquoting()
end)
it('spawns child process with UTF-8 codepage', function()
command('set shell=cmd.exe')
eq('тест\n', eval([[system('echo тест')]]))
end)
it('with shell=cmd', function()
command('set shell=cmd')
eq('"a b"\n', eval([[system('echo "a b"')]]))