aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--win32/process.c63
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)
119static char * 119static char *
120quote_arg(const char *arg) 120quote_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