From 661cc495b6b1a7fb5355eebe8c1976211aa2a458 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 13 Jan 2026 04:30:15 +0200 Subject: [PATCH] os: fix args quoting in win_spawn_process (fix #26261) (#26339) --- cmd/tools/test_os_args.v | 1 + vlib/os/process_args_test.v | 20 ++++++++++++++++++++ vlib/os/process_windows.c.v | 22 +++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 cmd/tools/test_os_args.v create mode 100644 vlib/os/process_args_test.v diff --git a/cmd/tools/test_os_args.v b/cmd/tools/test_os_args.v new file mode 100644 index 000000000..b5e2b0ec3 --- /dev/null +++ b/cmd/tools/test_os_args.v @@ -0,0 +1 @@ +println(arguments()#[1..]) diff --git a/vlib/os/process_args_test.v b/vlib/os/process_args_test.v new file mode 100644 index 000000000..f1bcc4b1e --- /dev/null +++ b/vlib/os/process_args_test.v @@ -0,0 +1,20 @@ +import os + +const vexe = os.getenv('VEXE') +const vroot = os.dir(vexe) + +fn test_v_run_simple() { + echo_os_args := os.join_path(vroot, 'cmd/tools/test_os_args.v') + res123 := os.execute('${os.quoted_path(vexe)} run ${os.quoted_path(echo_os_args)} 1 2 3') + println(res123) + assert res123.exit_code == 0 + assert res123.output.starts_with("['1', '2', '3']") +} + +fn test_v_run_quoted_args_with_spaces() { + echo_os_args := os.join_path(vroot, 'cmd/tools/test_os_args.v') + res := os.execute('${os.quoted_path(vexe)} run ${os.quoted_path(echo_os_args)} 1 "Learn V" 3') + println(res) + assert res.exit_code == 0 + assert res.output.starts_with("['1', 'Learn V', '3']") +} diff --git a/vlib/os/process_windows.c.v b/vlib/os/process_windows.c.v index f04c1c824..b666331c0 100644 --- a/vlib/os/process_windows.c.v +++ b/vlib/os/process_windows.c.v @@ -108,7 +108,7 @@ fn (mut p Process) win_spawn_process() int { start_info.h_std_error = wdata.child_stderr_write start_info.dw_flags = u32(C.STARTF_USESTDHANDLES) } - cmd := '${p.filename} ' + p.args.join(' ') + cmd := '${p.filename} ' + requote_args(p.args) cmd_wide_ptr := cmd.to_wide() to_be_freed << cmd_wide_ptr C.ExpandEnvironmentStringsW(cmd_wide_ptr, voidptr(&wdata.command_line[0]), 32768) @@ -367,3 +367,23 @@ fn (mut p Process) unix_wait() { fn (mut p Process) unix_is_alive() bool { return false } + +@[manualfree] +fn requote_args(cargs []string) string { + mut sb := strings.new_builder(128) + defer { unsafe { sb.free() } } + for idx, a in cargs { + if idx > 0 { + sb.write_rune(` `) + } + if !a.starts_with('"') { + sb.write_string('"') + sb.write_string(a) + sb.write_string('"') + } else { + sb.write_string(a) + } + } + res := sb.str() + return res +} -- 2.39.5