diff options
-rw-r--r-- | win32/process.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/win32/process.c b/win32/process.c index 2206a0a5e..951519e59 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -119,58 +119,91 @@ parse_interpreter(const char *cmd, char ***opts, int *nopts) | |||
119 | static char * | 119 | static char * |
120 | quote_arg(const char *arg) | 120 | quote_arg(const char *arg) |
121 | { | 121 | { |
122 | /* count chars to quote */ | ||
123 | int len = 0, n = 0; | 122 | int len = 0, n = 0; |
124 | int force_quotes = 0; | 123 | int force_quotes = 0; |
125 | char *q, *d; | 124 | char *q, *d; |
126 | const char *p = arg; | 125 | const char *p = arg; |
127 | if (!*p) force_quotes = 1; | 126 | |
127 | /* empty arguments must be quoted */ | ||
128 | if (!*p) { | ||
129 | force_quotes = 1; | ||
130 | } | ||
131 | |||
128 | while (*p) { | 132 | while (*p) { |
129 | if (isspace(*p)) | 133 | if (isspace(*p)) { |
134 | /* arguments containing whitespace must be quoted */ | ||
130 | force_quotes = 1; | 135 | force_quotes = 1; |
131 | else if (*p == '"') | 136 | } |
137 | else if (*p == '"') { | ||
138 | /* double quotes in arguments need to be escaped */ | ||
132 | n++; | 139 | n++; |
140 | } | ||
133 | else if (*p == '\\') { | 141 | else if (*p == '\\') { |
142 | /* count contiguous backslashes */ | ||
134 | int count = 0; | 143 | int count = 0; |
135 | while (*p == '\\') { | 144 | while (*p == '\\') { |
136 | count++; | 145 | count++; |
137 | p++; | 146 | p++; |
138 | len++; | 147 | len++; |
139 | } | 148 | } |
140 | if (*p == '"') | 149 | |
150 | /* | ||
151 | * Only escape backslashes before explicit double quotes or | ||
152 | * or where the backslashes are at the end of an argument | ||
153 | * that is scheduled to be quoted. | ||
154 | */ | ||
155 | if (*p == '"' || (force_quotes && *p == '\0')) { | ||
141 | n += count*2 + 1; | 156 | n += count*2 + 1; |
157 | } | ||
158 | |||
159 | if (*p == '\0') { | ||
160 | break; | ||
161 | } | ||
142 | continue; | 162 | continue; |
143 | } | 163 | } |
144 | len++; | 164 | len++; |
145 | p++; | 165 | p++; |
146 | } | 166 | } |
147 | if (!force_quotes && n == 0) | 167 | |
168 | if (!force_quotes && n == 0) { | ||
148 | return (char*)arg; | 169 | return (char*)arg; |
170 | } | ||
149 | 171 | ||
150 | /* insert \ where necessary */ | 172 | /* insert double quotes and backslashes where necessary */ |
151 | d = q = xmalloc(len+n+3); | 173 | d = q = xmalloc(len+n+3); |
152 | if (force_quotes) | 174 | if (force_quotes) { |
153 | *d++ = '"'; | 175 | *d++ = '"'; |
176 | } | ||
177 | |||
154 | while (*arg) { | 178 | while (*arg) { |
155 | if (*arg == '"') | 179 | if (*arg == '"') { |
156 | *d++ = '\\'; | 180 | *d++ = '\\'; |
181 | } | ||
157 | else if (*arg == '\\') { | 182 | else if (*arg == '\\') { |
158 | int count = 0; | 183 | int count = 0; |
159 | while (*arg == '\\') { | 184 | while (*arg == '\\') { |
160 | count++; | 185 | count++; |
161 | *d++ = *arg++; | 186 | *d++ = *arg++; |
162 | } | 187 | } |
163 | if (*arg == '"') { | 188 | |
164 | while (count-- > 0) | 189 | if (*arg == '"' || (force_quotes && *arg == '\0')) { |
190 | while (count-- > 0) { | ||
165 | *d++ = '\\'; | 191 | *d++ = '\\'; |
166 | *d++ = '\\'; | 192 | } |
193 | if (*arg == '"') { | ||
194 | *d++ = '\\'; | ||
195 | } | ||
167 | } | 196 | } |
168 | } | 197 | } |
169 | *d++ = *arg++; | 198 | if (*arg != '\0') { |
199 | *d++ = *arg++; | ||
200 | } | ||
170 | } | 201 | } |
171 | if (force_quotes) | 202 | if (force_quotes) { |
172 | *d++ = '"'; | 203 | *d++ = '"'; |
173 | *d++ = 0; | 204 | } |
205 | *d = '\0'; | ||
206 | |||
174 | return q; | 207 | return q; |
175 | } | 208 | } |
176 | 209 | ||