diff options
author | Ron Yorston <rmy@pobox.com> | 2023-04-27 07:31:23 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-04-27 07:31:23 +0100 |
commit | d0deef23fa6b228aea60b5599b5ba291ed0ad304 (patch) | |
tree | a722955c91cf1eff44d229d1a750188c8a875827 /win32/process.c | |
parent | cbbb73da90bac5029cbd58f4a8f148312768bc0f (diff) | |
download | busybox-w32-d0deef23fa6b228aea60b5599b5ba291ed0ad304.tar.gz busybox-w32-d0deef23fa6b228aea60b5599b5ba291ed0ad304.tar.bz2 busybox-w32-d0deef23fa6b228aea60b5599b5ba291ed0ad304.zip |
win32: code shrink quote_args()
Replace parts of quote_args() with code from avih's GitHub
PR #317.
This overestimates the size of the buffer to avoid having to
calculate the exact size.
Retain the code to determine whether the argument needs to be
quoted. Quoting arguments unconditionally wastes space on the
command line and causes the test "xargs argument line too long"
to fail.
Saves 144-176 bytes.
Diffstat (limited to '')
-rw-r--r-- | win32/process.c | 78 |
1 files changed, 20 insertions, 58 deletions
diff --git a/win32/process.c b/win32/process.c index 62be6e0cc..5dc0f7080 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -116,9 +116,10 @@ parse_interpreter(const char *cmd, interp_t *interp) | |||
116 | char * | 116 | char * |
117 | quote_arg(const char *arg) | 117 | quote_arg(const char *arg) |
118 | { | 118 | { |
119 | int len = 0, n = 0; | ||
120 | int force_quotes = 0; | 119 | int force_quotes = 0; |
121 | char *q, *d; | 120 | char *r = xmalloc(2 * strlen(arg) + 3); // max-esc, enclosing DQ, \0 |
121 | char *d = r; | ||
122 | int nbs = 0; // n consecutive BS right before current char | ||
122 | const char *p = arg; | 123 | const char *p = arg; |
123 | 124 | ||
124 | /* empty arguments must be quoted */ | 125 | /* empty arguments must be quoted */ |
@@ -130,78 +131,39 @@ quote_arg(const char *arg) | |||
130 | if (isspace(*p)) { | 131 | if (isspace(*p)) { |
131 | /* arguments containing whitespace must be quoted */ | 132 | /* arguments containing whitespace must be quoted */ |
132 | force_quotes = 1; | 133 | force_quotes = 1; |
134 | break; | ||
133 | } | 135 | } |
134 | else if (*p == '"') { | ||
135 | /* double quotes in arguments need to be escaped */ | ||
136 | n++; | ||
137 | } | ||
138 | else if (*p == '\\') { | ||
139 | /* count contiguous backslashes */ | ||
140 | int count = 0; | ||
141 | while (*p == '\\') { | ||
142 | count++; | ||
143 | p++; | ||
144 | len++; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Only escape backslashes before explicit double quotes or | ||
149 | * or where the backslashes are at the end of an argument | ||
150 | * that is scheduled to be quoted. | ||
151 | */ | ||
152 | if (*p == '"' || (force_quotes && *p == '\0')) { | ||
153 | n += count*2 + 1; | ||
154 | } | ||
155 | |||
156 | if (*p == '\0') { | ||
157 | break; | ||
158 | } | ||
159 | continue; | ||
160 | } | ||
161 | len++; | ||
162 | p++; | 136 | p++; |
163 | } | 137 | } |
164 | 138 | ||
165 | if (!force_quotes && n == 0) { | ||
166 | return xstrdup(arg); | ||
167 | } | ||
168 | |||
169 | /* insert double quotes and backslashes where necessary */ | 139 | /* insert double quotes and backslashes where necessary */ |
170 | d = q = xmalloc(len+n+3); | ||
171 | if (force_quotes) { | 140 | if (force_quotes) { |
172 | *d++ = '"'; | 141 | *d++ = '"'; |
173 | } | 142 | } |
174 | 143 | ||
175 | while (*arg) { | 144 | while (*arg) { |
176 | if (*arg == '"') { | 145 | switch (*arg) { |
177 | *d++ = '\\'; | 146 | case '\\': |
178 | } | 147 | ++nbs; |
179 | else if (*arg == '\\') { | 148 | break; |
180 | int count = 0; | 149 | case '"': // double consecutive-BS, plus one to escape the DQ |
181 | while (*arg == '\\') { | 150 | for (++nbs; nbs; --nbs) |
182 | count++; | 151 | *d++ = '\\'; |
183 | *d++ = *arg++; | 152 | break; |
184 | } | 153 | default: // reset count if followed by not-DQ |
185 | 154 | nbs = 0; | |
186 | if (*arg == '"' || (force_quotes && *arg == '\0')) { | ||
187 | while (count-- > 0) { | ||
188 | *d++ = '\\'; | ||
189 | } | ||
190 | if (*arg == '"') { | ||
191 | *d++ = '\\'; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | if (*arg != '\0') { | ||
196 | *d++ = *arg++; | ||
197 | } | 155 | } |
156 | *d++ = *arg++; | ||
198 | } | 157 | } |
158 | |||
199 | if (force_quotes) { | 159 | if (force_quotes) { |
160 | while (nbs--) // double consecutive-BS before the closing DQ | ||
161 | *d++ = '\\'; | ||
200 | *d++ = '"'; | 162 | *d++ = '"'; |
201 | } | 163 | } |
202 | *d = '\0'; | 164 | *d++ = '\0'; |
203 | 165 | ||
204 | return q; | 166 | return xrealloc(r, d - r); |
205 | } | 167 | } |
206 | 168 | ||
207 | char * | 169 | char * |