4 /* Help to copy the thing properly quoted for the shell safety.
5 * any single quote is replaced with '\'', any exclamation point
6 * is replaced with '\!', and the whole thing is enclosed in a
9 * original sq_quote result
10 * name ==> name ==> 'name'
11 * a b ==> a b ==> 'a b'
12 * a'b ==> a'\''b ==> 'a'\''b'
13 * a!b ==> a'\!'b ==> 'a'\!'b'
16 #define EMIT(x) do { if (++len < n) *bp++ = (x); } while(0)
18 static inline int need_bs_quote(char c)
20 return (c == '\'' || c == '!');
23 static size_t sq_quote_buf(char *dst, size_t n, const char *src)
30 while ((c = *src++)) {
31 if (need_bs_quote(c)) {
48 void sq_quote_print(FILE *stream, const char *src)
53 while ((c = *src++)) {
54 if (need_bs_quote(c)) {
65 char *sq_quote_argv(const char** argv, int count)
71 /* Count argv if needed. */
73 for (count = 0; argv[count]; count++)
77 /* Special case: no argv. */
81 /* Get destination buffer length. */
82 for (i = 0; i < count; i++)
83 len += sq_quote_buf(NULL, 0, argv[i]) + 1;
85 /* Alloc destination buffer. */
86 to = buf = xmalloc(len + 1);
88 /* Copy into destination buffer. */
89 for (i = 0; i < count; ++i) {
91 to += sq_quote_buf(to, len, argv[i]);
98 * Append a string to a string buffer, with or without shell quoting.
99 * Return true if the buffer overflowed.
101 int add_to_string(char **ptrp, int *sizep, const char *str, int quote)
109 oc = sq_quote_buf(p, size, str);
112 memcpy(p, str, (size <= oc) ? size - 1 : oc);
126 char *sq_dequote(char *arg)
142 /* We stepped out of sq */
149 if (need_bs_quote(c) && *++src == '\'') {
160 /* 1 means: quote as octal
161 * 0 means: quote as octal if (quote_path_fully)
162 * -1 means: never quote
165 #define X8(x) x, x, x, x, x, x, x, x
166 #define X16(x) X8(x), X8(x)
167 static signed char const sq_lookup[256] = {
168 /* 0 1 2 3 4 5 6 7 */
169 /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 'a',
170 /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r', 1, 1,
172 /* 0x20 */ -1, -1, '"', -1, -1, -1, -1, -1,
173 /* 0x28 */ X16(-1), X16(-1), X16(-1),
174 /* 0x58 */ -1, -1, -1, -1,'\\', -1, -1, -1,
175 /* 0x60 */ X16(-1), X8(-1),
176 /* 0x78 */ -1, -1, -1, -1, -1, -1, -1, 1,
177 /* 0x80 */ /* set to 0 */
180 static inline int sq_must_quote(char c) {
181 return sq_lookup[(unsigned char)c] + quote_path_fully > 0;
184 /* returns the longest prefix not needing a quote up to maxlen if positive.
185 This stops at the first \0 because it's marked as a character needing an
187 static size_t next_quote_pos(const char *s, ssize_t maxlen)
191 for (len = 0; !sq_must_quote(s[len]); len++);
193 for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++);
199 * C-style name quoting.
201 * (1) if sb and fp are both NULL, inspect the input name and counts the
202 * number of bytes that are needed to hold c_style quoted version of name,
203 * counting the double quotes around it but not terminating NUL, and
205 * However, if name does not need c_style quoting, it returns 0.
207 * (2) if sb or fp are not NULL, it emits the c_style quoted version
208 * of name, enclosed with double quotes if asked and needed only.
209 * Return value is the same as in (1).
211 static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
212 struct strbuf *sb, FILE *fp, int no_dq)
217 if (sb) strbuf_addch(sb, (c)); \
218 if (fp) fputc((c), fp); \
221 #define EMITBUF(s, l) \
223 if (sb) strbuf_add(sb, (s), (l)); \
224 if (fp) fwrite((s), (l), 1, fp); \
228 size_t len, count = 0;
229 const char *p = name;
234 len = next_quote_pos(p, maxlen);
235 if (len == maxlen || !p[len])
238 if (!no_dq && p == name)
244 ch = (unsigned char)*p++;
245 if (sq_lookup[ch] >= ' ') {
248 EMIT(((ch >> 6) & 03) + '0');
249 EMIT(((ch >> 3) & 07) + '0');
250 EMIT(((ch >> 0) & 07) + '0');
255 if (p == name) /* no ending quote needed */
263 size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq)
265 return quote_c_style_counted(name, -1, sb, fp, nodq);
268 void write_name_quoted(const char *name, FILE *fp, int terminator)
271 quote_c_style(name, NULL, fp, 0);
275 fputc(terminator, fp);
278 extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
279 const char *name, FILE *fp, int terminator)
284 needquote = next_quote_pos(pfx, pfxlen) < pfxlen
285 || name[next_quote_pos(name, -1)];
289 quote_c_style_counted(pfx, pfxlen, NULL, fp, 1);
290 quote_c_style(name, NULL, fp, 1);
293 fwrite(pfx, pfxlen, 1, fp);
296 fputc(terminator, fp);
300 * C-style name unquoting.
302 * Quoted should point at the opening double quote.
303 * + Returns 0 if it was able to unquote the string properly, and appends the
304 * result in the strbuf `sb'.
305 * + Returns -1 in case of error, and doesn't touch the strbuf. Though note
306 * that this function will allocate memory in the strbuf, so calling
307 * strbuf_release is mandatory whichever result unquote_c_style returns.
309 * Updates endp pointer to point at one past the ending double quote if given.
311 int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
313 size_t oldlen = sb->len, len;
316 if (*quoted++ != '"')
320 len = strcspn(quoted, "\"\\");
321 strbuf_add(sb, quoted, len);
335 switch ((ch = *quoted++)) {
336 case 'a': ch = '\a'; break;
337 case 'b': ch = '\b'; break;
338 case 'f': ch = '\f'; break;
339 case 'n': ch = '\n'; break;
340 case 'r': ch = '\r'; break;
341 case 't': ch = '\t'; break;
342 case 'v': ch = '\v'; break;
345 break; /* verbatim */
347 /* octal values with first digit over 4 overflow */
348 case '0': case '1': case '2': case '3':
349 ac = ((ch - '0') << 6);
350 if ((ch = *quoted++) < '0' || '7' < ch)
352 ac |= ((ch - '0') << 3);
353 if ((ch = *quoted++) < '0' || '7' < ch)
361 strbuf_addch(sb, ch);
365 strbuf_setlen(sb, oldlen);
369 /* quoting as a string literal for other languages */
371 void perl_quote_print(FILE *stream, const char *src)
373 const char sq = '\'';
374 const char bq = '\\';
378 while ((c = *src++)) {
379 if (c == sq || c == bq)
386 void python_quote_print(FILE *stream, const char *src)
388 const char sq = '\'';
389 const char bq = '\\';
390 const char nl = '\n';
394 while ((c = *src++)) {
400 if (c == sq || c == bq)
407 void tcl_quote_print(FILE *stream, const char *src)
412 while ((c = *src++)) {
416 case '$': case '\\': case '"':
422 fputs("\\f", stream);
425 fputs("\\r", stream);
428 fputs("\\n", stream);
431 fputs("\\t", stream);
434 fputs("\\v", stream);