diff options
author | Brad King <brad.king@kitware.com> | 2003-07-03 22:33:53 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2003-07-03 22:33:53 (GMT) |
commit | 33566642a0c89c24a6167c3661fdf7e66a104c20 (patch) | |
tree | 98847045f719e9833e364be8b272a4dc3c7894a4 | |
parent | f22a4a908ddf52f7c6fd3d9cdedd43eaeda734f0 (diff) | |
download | CMake-33566642a0c89c24a6167c3661fdf7e66a104c20.zip CMake-33566642a0c89c24a6167c3661fdf7e66a104c20.tar.gz CMake-33566642a0c89c24a6167c3661fdf7e66a104c20.tar.bz2 |
BUG: Argument parsers do not always remove double quotes from around an argument that has no spaces.
-rw-r--r-- | Source/kwsys/ProcessWin32.c | 174 |
1 files changed, 108 insertions, 66 deletions
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index 28db911..0eebb5e 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -442,11 +442,12 @@ void kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) if(command) { /* We need to construct a single string representing the command - and its arguments. We will surround each argument with - double-quotes so it can contain spaces. 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. */ + 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; @@ -456,38 +457,56 @@ void kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) /* Keep track of how many backslashes have been encountered in a row in this argument. */ int backslashes = 0; + int spaces = 0; const char* c; - /* Add the length of the argument, plus 3 for the double quotes - and space separating the arguments. */ - length += (int)strlen(*arg) + 3; - - /* Scan the string to find characters that need escaping. */ + /* Scan the string for spaces. If there are no spaces, we can + pass the argument verbatim. */ for(c=*arg; *c; ++c) { - if(*c == '\\') - { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; - } - else if(*c == '"') + if(*c == ' ' || *c == '\t') { - /* Found a double-quote. We need to escape it and all - immediately preceding backslashes. */ - length += backslashes + 1; - backslashes = 0; + spaces = 1; + break; } - else + } + + /* Add the length of the argument, plus 1 for the space + separating the arguments. */ + length += (int)strlen(*arg) + 1; + + 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) { - /* Found another character. This eliminates the possibility - that any immediately preceding backslashes will be - escaped. */ - backslashes = 0; + 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; + } } - } - /* 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 @@ -502,65 +521,88 @@ void kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) /* 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 + 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) { *cmd++ = ' '; } - - /* Add the opening double-quote for this argument. */ - *cmd++ = '"'; - - /* Add the characters of the argument, possibly escaping them. */ - for(c=*arg; *c; ++c) + + if(spaces) { - if(*c == '\\') - { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; - *cmd++ = '\\'; - } - else if(*c == '"') + /* Add the opening double-quote for this argument. */ + *cmd++ = '"'; + + /* Add the characters of the argument, possibly escaping them. */ + for(c=*arg; *c; ++c) { - /* Add enough backslashes to escape any that preceded the - double-quote. */ - while(backslashes > 0) + if(*c == '\\') { - --backslashes; + /* Found a backslash. It may need to be escaped later. */ + ++backslashes; *cmd++ = '\\'; } - - /* Add the backslash to escape the double-quote. */ - *cmd++ = '\\'; - - /* Add the double-quote itself. */ - *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 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; + } } - else + + /* Add enough backslashes to escape any trailing ones. */ + while(backslashes > 0) { - /* We encountered a normal character. This eliminates any - escaping needed for preceding backslashes. Add the - character. */ - backslashes = 0; - *cmd++ = *c; + --backslashes; + *cmd++ = '\\'; } + + /* Add the closing double-quote for this argument. */ + *cmd++ = '"'; } - - /* Add enough backslashes to escape any trailing ones. */ - while(backslashes > 0) + else { - --backslashes; - *cmd++ = '\\'; + /* No spaces. Add the argument verbatim. */ + for(c=*arg; *c; ++c) + { + *cmd++ = *c; + } } - - /* Add the opening double-quote for this argument. */ - *cmd++ = '"'; } /* Add the terminating null character to the command line. */ - *cmd++ = 0; + *cmd = 0; } } |