From: norbert.bizet Date: Mon, 13 Mar 2023 14:54:04 +0000 (-0400) Subject: allow double quote escaping in win32 bpipe X-Git-Tag: Beta-15.0.0~219 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4631fa207f7d58af197a5317adca978134067643;p=thirdparty%2Fbacula.git allow double quote escaping in win32 bpipe --- diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index 4eb05d442..e1833b32e 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -512,7 +512,7 @@ int run_program(char *prog, int wait, POOLMEM *&results) * non-zero on error == berrno status * */ -int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]) +int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[], bool cmd_string_opt) { BPIPE *bpipe; int stat1=0, stat2=0, stat3=0; @@ -536,7 +536,12 @@ int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, P mode = (char *)"re"; } +#ifdef HAVE_WIN32 + bpipe = open_bpipe(prog, wait, mode, env, cmd_string_opt); +#else + (void) cmd_string_opt; bpipe = open_bpipe(prog, wait, mode, env); +#endif if (!bpipe) { stat1 = ENOENT; goto bail_out; @@ -635,7 +640,7 @@ bail_out: int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[]) { char *errors = NULL; - return run_program_full_output_and_error(prog, wait, results, errors, env); + return run_program_full_output_and_error(prog, wait, results, errors, env, false); } /* diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 644622b55..ad2689171 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -167,7 +167,12 @@ int set_socket_errno(int sockstat); int bget_msg(BSOCK *sock); /* bpipe.c */ +#ifdef HAVE_WIN32 +/* cmd_string_opt adds /s option to cmd invocation (win32 only)*/ +BPIPE * open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL, bool cmd_string_opt = false); +#else BPIPE * open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL); +#endif int close_wpipe(BPIPE *bpipe); int close_epipe(BPIPE *bpipe); int close_bpipe(BPIPE *bpipe); @@ -432,7 +437,7 @@ void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); void jobstatus_to_ascii_gui (int JobStatus, char *msg, int maxlen); int run_program (char *prog, int wait, POOLMEM *&results); int run_program_full_output (char *prog, int wait, POOLMEM *&results, char *env[]=NULL); -int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL); +int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL, bool cmd_string_opt=false); char * action_on_purge_to_string(int aop, POOL_MEM &ret); const char * job_type_to_str (int type); const char * job_status_to_str (int stat, int errors); diff --git a/bacula/src/win32/compat/compat.cpp b/bacula/src/win32/compat/compat.cpp index 55407228d..2b16ca232 100644 --- a/bacula/src/win32/compat/compat.cpp +++ b/bacula/src/win32/compat/compat.cpp @@ -2640,7 +2640,7 @@ CreateChildProcessA(const char *comspec, char *cmdLine, */ HANDLE CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err, - char * envp[] = NULL) + char * envp[] = NULL, bool cmd_string_opt = false) { static const char *comspec = NULL; PROCESS_INFORMATION piProcInfo; @@ -2676,7 +2676,18 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err, } POOL_MEM cmdLine(PM_FNAME); - Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart); + if (cmd_string_opt) { + /* For working around multiple double quotes in the exe and arguments, we use the /s cmd option */ + /* /s skips the parsing rules of /c and only strips the first and last quote so: + /* cmd.exe /s /c ""C:\program files\myexe.exe" -file "C:\program files\args.txt"" will respect both */ + /* "C:\program files\myexe.exe" and "C:\program files\args.txt" quotes */ + Mmsg(cmdLine, "%s /s /c \"\"%s\"%s\"", comspec, exeFile, argStart); + } else { + /* regular cmd call: cmd.exe /c "C:\program files\myexe.exe" -args C:\PROGR~1\args.txt */ + /* arguments should not contain double quotes */ + Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart); + } + free(exeFile); @@ -2737,7 +2748,7 @@ CloseHandleIfValid(HANDLE handle) #define MODE_NOSTDERR 16 BPIPE * -open_bpipe(char *prog, int wait, const char *mode, char *envp[]) +open_bpipe(char *prog, int wait, const char *mode, char *envp[], bool cmd_string_opt) { HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup, @@ -2850,7 +2861,8 @@ open_bpipe(char *prog, int wait, const char *mode, char *envp[]) hChildStdoutWr, // stdout HANDLE (mode_map & MODE_STDERR || mode_map & MODE_NOSTDERR) ? hChildStderrWr:hChildStdoutWr, // stderr HANDLE - envp); // envp environment variables are added to the current process env var set. + envp, + cmd_string_opt); // envp environment variables are added to the current process env var set. if ((HANDLE) bpipe->worker_pid == INVALID_HANDLE_VALUE) { ErrorExit("CreateChildProcess failed");