--- parser3/src/main/pa_exec.C 2017/02/06 16:17:12 1.92 +++ parser3/src/main/pa_exec.C 2024/11/24 16:55:21 1.100 @@ -1,8 +1,8 @@ /** @file Parser: program executing for different OS-es. - Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian @todo setrlimit */ @@ -13,7 +13,7 @@ #include "pa_exception.h" #include "pa_common.h" -volatile const char * IDENT_PA_EXEC_C="$Id: pa_exec.C,v 1.92 2017/02/06 16:17:12 moko Exp $" IDENT_PA_EXEC_H; +volatile const char * IDENT_PA_EXEC_C="$Id: pa_exec.C,v 1.100 2024/11/24 16:55:21 moko Exp $" IDENT_PA_EXEC_H; #ifdef _MSC_VER @@ -79,7 +79,7 @@ static DWORD CreateHiddenConsoleProcess( // calculating script's directory char dir[MAX_STRING]; - strncpy(dir, szScriptFileSpec, MAX_STRING-1); dir[MAX_STRING-1]=0; + pa_strncpy(dir, szScriptFileSpec, MAX_STRING); lsplit(dir,' '); // trim arguments rsplit(dir,'/'); rsplit(dir,'\\'); // trim filename @@ -165,6 +165,37 @@ static void read_pipe(File_read_result& } } +static const char* shell_quote(const char *arg) { + size_t length = strlen(arg); + if (length >= 2 && arg[0] == '"' && arg[length - 1] == '"') + return arg; // allready qouted + + size_t extra_length = 2; // opening and closing quotes + for(const char *src = arg; *src; src++){ + if (strchr("\"\\&|<>^()", *src)) + extra_length++; + } + + char *result = (char *)pa_malloc(length + extra_length + 1); + char *dest = result; + + *dest++ = '"'; + + for(const char *src=arg; *src;){ + char c = *src++; + if(c == '"' || c == '\\'){ + *dest++ = '\\'; // required for any program + } else if (strchr("&|<>^()", c)){ + *dest++ = '^'; // cmd.exe (.bat) specific + } + *dest++ = c; + } + + *dest++ = '"'; + *dest = '\0'; + return result; +} + static const char* buildCommand(const char* file_spec_cstr, const ArrayString& argv) { const char* result=file_spec_cstr; if(FILE *f=pa_fopen(file_spec_cstr, "r")) { @@ -194,7 +225,7 @@ static const char* buildCommand(const ch String string(result); for(size_t i=0; icstr()); } result=string.cstr(); @@ -283,7 +314,7 @@ static pid_t execve_piped(const char* fi // chdir to script's directory char dir[MAX_STRING]; - strncpy(dir, file_spec_cstr, MAX_STRING-1); dir[MAX_STRING-1]=0; + pa_strncpy(dir, file_spec_cstr, MAX_STRING); rsplit(dir,'/'); // trim filename chdir(dir); @@ -313,7 +344,7 @@ static pid_t execve_piped(const char* fi } static int get_exit_status(int pid) { - int status; + int status=0; pid_t cid; while ((cid=waitpid(pid, &status, WUNTRACED)) == -1 && errno == EINTR); if(!cid) @@ -368,7 +399,6 @@ struct Append_env_pair_info { }; #endif -///@test maybe here and at argv construction --- untaint_cstr(String::L_AS_IS static void append_env_pair(HashStringString::key_type key, HashStringString::value_type value, Append_env_pair_info *info) { #ifdef _MSC_VER