diff --git a/ProcessWin32.c b/ProcessWin32.c index f7480de38b039c35ae311768f20c32584214aaeb..aa3fb60f3e07605bb7d9293bb1f11122dddea67e 100644 --- a/ProcessWin32.c +++ b/ProcessWin32.c @@ -502,178 +502,177 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) } } - if(command) - { - /* We need to construct a single string representing the command + /* We need to construct a single string representing the command and its arguments. We will surround each argument containing spaces with double-quotes. Inside a double-quoted argument, we need to escape double-quotes and all backslashes before them. We also need to escape backslashes at the end of an argument because they come before the closing double-quote for the argument. */ - char* cmd; - char const* const* arg; - int length = 0; - /* First determine the length of the final string. */ - for(arg = command; *arg; ++arg) - { - /* Keep track of how many backslashes have been encountered in a - row in this argument. */ - int backslashes = 0; - int spaces = 0; - const char* c; - - /* Scan the string for spaces. If there are no spaces, we can + { + char* cmd; + char const* const* arg; + int length = 0; + /* First determine the length of the final string. */ + for(arg = command; *arg; ++arg) + { + /* Keep track of how many backslashes have been encountered in a + row in this argument. */ + int backslashes = 0; + int spaces = 0; + const char* c; + + /* Scan the string for spaces. If there are no spaces, we can pass the argument verbatim. */ - for(c=*arg; *c; ++c) + for(c=*arg; *c; ++c) + { + if(*c == ' ' || *c == '\t') { - if(*c == ' ' || *c == '\t') - { - spaces = 1; - break; - } + spaces = 1; + break; } + } - /* Add the length of the argument, plus 1 for the space + /* Add the length of the argument, plus 1 for the space separating the arguments. */ - length += (int)strlen(*arg) + 1; + length += (int)strlen(*arg) + 1; - if(spaces) - { - /* Add 2 for double quotes since spaces are present. */ - length += 2; + if(spaces) + { + /* Add 2 for double quotes since spaces are present. */ + length += 2; /* Scan the string to find characters that need escaping. */ - for(c=*arg; *c; ++c) + for(c=*arg; *c; ++c) + { + if(*c == '\\') { - if(*c == '\\') - { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; - } - else if(*c == '"') - { - /* Found a double-quote. We need to escape it and all - immediately preceding backslashes. */ - length += backslashes + 1; - backslashes = 0; - } - else - { - /* Found another character. This eliminates the possibility - that any immediately preceding backslashes will be - escaped. */ - backslashes = 0; - } + /* Found a backslash. It may need to be escaped later. */ + ++backslashes; + } + else if(*c == '"') + { + /* Found a double-quote. We need to escape it and all + immediately preceding backslashes. */ + length += backslashes + 1; + backslashes = 0; + } + else + { + /* Found another character. This eliminates the possibility + that any immediately preceding backslashes will be + escaped. */ + backslashes = 0; } - - /* We need to escape all ending backslashes. */ - length += backslashes; } + + /* We need to escape all ending backslashes. */ + length += backslashes; } + } - /* Allocate enough space for the command. We do not need an extra + /* Allocate enough space for the command. We do not need an extra byte for the terminating null because we allocated a space for the first argument that we will not use. */ - newCommands[cp->NumberOfCommands] = (char*)malloc(length); - if(!newCommands[cp->NumberOfCommands]) - { - /* Out of memory. */ - free(newCommands); - return 0; - } + newCommands[cp->NumberOfCommands] = (char*)malloc(length); + if(!newCommands[cp->NumberOfCommands]) + { + /* Out of memory. */ + free(newCommands); + return 0; + } - /* Construct the command line in the allocated buffer. */ - cmd = newCommands[cp->NumberOfCommands]; - for(arg = command; *arg; ++arg) - { - /* Keep track of how many backslashes have been encountered in a - row in an argument. */ - int backslashes = 0; - int spaces = 0; - const char* c; + /* Construct the command line in the allocated buffer. */ + cmd = newCommands[cp->NumberOfCommands]; + for(arg = command; *arg; ++arg) + { + /* Keep track of how many backslashes have been encountered in a + row in an argument. */ + int backslashes = 0; + int spaces = 0; + const char* c; - /* Scan the string for spaces. If there are no spaces, we can + /* Scan the string for spaces. If there are no spaces, we can pass the argument verbatim. */ - for(c=*arg; *c; ++c) - { - if(*c == ' ' || *c == '\t') - { - spaces = 1; - break; - } - } - - /* Add the separating space if this is not the first argument. */ - if(arg != command) + for(c=*arg; *c; ++c) + { + if(*c == ' ' || *c == '\t') { - *cmd++ = ' '; + spaces = 1; + break; } + } - if(spaces) - { - /* Add the opening double-quote for this argument. */ - *cmd++ = '"'; + /* Add the separating space if this is not the first argument. */ + if(arg != command) + { + *cmd++ = ' '; + } + + if(spaces) + { + /* Add the opening double-quote for this argument. */ + *cmd++ = '"'; /* Add the characters of the argument, possibly escaping them. */ - for(c=*arg; *c; ++c) + for(c=*arg; *c; ++c) + { + if(*c == '\\') { - if(*c == '\\') + /* Found a backslash. It may need to be escaped later. */ + ++backslashes; + *cmd++ = '\\'; + } + else if(*c == '"') + { + /* Add enough backslashes to escape any that preceded the + double-quote. */ + while(backslashes > 0) { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; + --backslashes; *cmd++ = '\\'; } - else if(*c == '"') - { - /* Add enough backslashes to escape any that preceded the - double-quote. */ - while(backslashes > 0) - { - --backslashes; - *cmd++ = '\\'; - } - /* Add the backslash to escape the double-quote. */ - *cmd++ = '\\'; + /* Add the backslash to escape the double-quote. */ + *cmd++ = '\\'; - /* Add the double-quote itself. */ - *cmd++ = '"'; - } - else - { - /* We encountered a normal character. This eliminates any - escaping needed for preceding backslashes. Add the - character. */ - backslashes = 0; - *cmd++ = *c; - } + /* Add the double-quote itself. */ + *cmd++ = '"'; } - - /* Add enough backslashes to escape any trailing ones. */ - while(backslashes > 0) + else { - --backslashes; - *cmd++ = '\\'; + /* We encountered a normal character. This eliminates any + escaping needed for preceding backslashes. Add the + character. */ + backslashes = 0; + *cmd++ = *c; } - - /* Add the closing double-quote for this argument. */ - *cmd++ = '"'; } - else + + /* Add enough backslashes to escape any trailing ones. */ + while(backslashes > 0) { - /* No spaces. Add the argument verbatim. */ - for(c=*arg; *c; ++c) - { - *cmd++ = *c; - } + --backslashes; + *cmd++ = '\\'; + } + + /* Add the closing double-quote for this argument. */ + *cmd++ = '"'; + } + else + { + /* No spaces. Add the argument verbatim. */ + for(c=*arg; *c; ++c) + { + *cmd++ = *c; } } - - /* Add the terminating null character to the command line. */ - *cmd = 0; } + /* Add the terminating null character to the command line. */ + *cmd = 0; + } + /* Save the new array of commands. */ free(cp->Commands); cp->Commands = newCommands;