diff options
-rw-r--r-- | win32/process.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/win32/process.c b/win32/process.c index a70b9484e..e7c9ca187 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -109,38 +109,34 @@ parse_interpreter(const char *cmd, interp_t *interp) | |||
109 | char * FAST_FUNC | 109 | char * FAST_FUNC |
110 | quote_arg(const char *arg) | 110 | quote_arg(const char *arg) |
111 | { | 111 | { |
112 | char *r = xmalloc(2 * strlen(arg) + 3); // max-esc, enclosing DQ, \0 | 112 | char *d, *r = xmalloc(2 * strlen(arg) + 3); // max-esc, quotes, \0 |
113 | char *d = r; | 113 | size_t nbs = 0; // consecutive backslashes before current char |
114 | int nbs = 0; // n consecutive BS right before current char | 114 | int quoted = !*arg; |
115 | 115 | ||
116 | /* empty arguments and those containing tab/space must be quoted */ | 116 | for (d = r; *arg; *d++ = *arg++) { |
117 | if (!*arg || strpbrk(arg, " \t")) { | 117 | if (*arg == ' ' || *arg == '\t') |
118 | *d++ = '"'; | 118 | quoted = 1; |
119 | } | 119 | |
120 | if (*arg == '\\' || *arg == '"') | ||
121 | *d++ = '\\'; | ||
122 | else | ||
123 | d -= nbs; // undo nbs escapes, if any (not followed by DQ) | ||
120 | 124 | ||
121 | while (*arg) { | 125 | if (*arg == '\\') |
122 | switch (*arg) { | ||
123 | case '\\': | ||
124 | ++nbs; | 126 | ++nbs; |
125 | break; | 127 | else |
126 | case '"': // double consecutive-BS, plus one to escape the DQ | ||
127 | for (++nbs; nbs; --nbs) | ||
128 | *d++ = '\\'; | ||
129 | break; | ||
130 | default: // reset count if followed by not-DQ | ||
131 | nbs = 0; | 128 | nbs = 0; |
132 | } | ||
133 | *d++ = *arg++; | ||
134 | } | 129 | } |
135 | 130 | ||
136 | if (*r == '"') { | 131 | if (quoted) { |
137 | while (nbs--) // double consecutive-BS before the closing DQ | 132 | memmove(r + 1, r, d++ - r); |
138 | *d++ = '\\'; | 133 | *r = *d++ = '"'; |
139 | *d++ = '"'; | 134 | } else { |
135 | d -= nbs; | ||
140 | } | 136 | } |
141 | *d++ = '\0'; | ||
142 | 137 | ||
143 | return xrealloc(r, d - r); | 138 | *d = 0; |
139 | return r; | ||
144 | } | 140 | } |
145 | 141 | ||
146 | char * FAST_FUNC | 142 | char * FAST_FUNC |