win32unix: quote the arguments to the Unix.exec* functions (#9550)

Otherwise, arguments get split at spaces.
This is the same quoting that the Win32 implementation of
Unix.create_process does.

A test was added.

Fixes: 9320
master
Xavier Leroy 2020-05-14 18:15:10 +02:00 committed by GitHub
parent 1a8a4dfd85
commit 914dd057b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 12 deletions

View File

@ -247,6 +247,11 @@ OCaml 4.11
of dynlinked modules.
(Nicolás Ojeda Bär, review by Xavier Clerc and Gabriel Scherer)
- #9320, #9550: under Windows, make sure that the Unix.exec* functions
properly quote their argument lists.
(Xavier Leroy, report by André Maroneze, review by Nicolás Ojeda Bär
and David Allsopp)
- #9490, #9505: ensure proper rounding of file times returned by
Unix.stat, Unix.lstat, Unix.fstat.
(Xavier Leroy and Guillaume Melquiond, report by David Brown,

View File

@ -215,10 +215,29 @@ type wait_flag =
type file_descr
external execv : string -> string array -> 'a = "unix_execv"
external execve : string -> string array -> string array -> 'a = "unix_execve"
external execvp : string -> string array -> 'a = "unix_execvp"
external execvpe : string -> string array -> string array -> 'a = "unix_execvpe"
let maybe_quote f =
if String.contains f ' ' ||
String.contains f '\"' ||
String.contains f '\t' ||
f = ""
then Filename.quote f
else f
external sys_execv : string -> string array -> 'a = "unix_execv"
external sys_execve :
string -> string array -> string array -> 'a = "unix_execve"
external sys_execvp : string -> string array -> 'a = "unix_execvp"
external sys_execvpe :
string -> string array -> string array -> 'a = "unix_execvpe"
let execv prog args =
sys_execv prog (Array.map maybe_quote args)
let execve prog args env =
sys_execve prog (Array.map maybe_quote args) env
let execvp prog args =
sys_execvp prog (Array.map maybe_quote args)
let execvpe prog args env =
sys_execvpe prog (Array.map maybe_quote args) env
external waitpid : wait_flag list -> int -> int * process_status
= "win_waitpid"
@ -935,13 +954,6 @@ external win_create_process : string -> string -> string option ->
= "win_create_process" "win_create_process_native"
let make_cmdline args =
let maybe_quote f =
if String.contains f ' ' ||
String.contains f '\"' ||
String.contains f '\t' ||
f = ""
then Filename.quote f
else f in
String.concat " " (List.map maybe_quote (Array.to_list args))
let make_process_env env =

View File

@ -50,6 +50,9 @@ let run args =
let _, exit = waitpid [] pid in
assert (exit = WEXITED 0)
let exec args =
execv ("./" ^ prog_name) (Array.of_list (prog_name :: args))
let () =
List.iter run
[
@ -60,4 +63,14 @@ let () =
[" \\ \\ \\\\\\"];
[" \"hola \""];
["a\tb"];
]
];
Printf.printf "-- execv\n%!";
exec [
"";
"a"; "b"; "c.txt@!";
"\"";
" "; " a "; " \" \\\" ";
" \\ \\ \\\\\\";
" \"hola \"";
"a\tb"
]

View File

@ -11,3 +11,15 @@
" \\ \\ \\\\\\" -> " \\ \\ \\\\\\" [OK]
" \"hola \"" -> " \"hola \"" [OK]
"a\tb" -> "a\tb" [OK]
-- execv
a
b
c.txt@!
"
a
" \"
\ \ \\\
"hola "
a b