Merge branch 'ew/hashmap'
[git] / quote.c
1 #include "cache.h"
2 #include "quote.h"
3 #include "argv-array.h"
4
5 int quote_path_fully = 1;
6
7 static inline int need_bs_quote(char c)
8 {
9         return (c == '\'' || c == '!');
10 }
11
12 /* Help to copy the thing properly quoted for the shell safety.
13  * any single quote is replaced with '\'', any exclamation point
14  * is replaced with '\!', and the whole thing is enclosed in a
15  * single quote pair.
16  *
17  * E.g.
18  *  original     sq_quote     result
19  *  name     ==> name      ==> 'name'
20  *  a b      ==> a b       ==> 'a b'
21  *  a'b      ==> a'\''b    ==> 'a'\''b'
22  *  a!b      ==> a'\!'b    ==> 'a'\!'b'
23  */
24 void sq_quote_buf(struct strbuf *dst, const char *src)
25 {
26         char *to_free = NULL;
27
28         if (dst->buf == src)
29                 to_free = strbuf_detach(dst, NULL);
30
31         strbuf_addch(dst, '\'');
32         while (*src) {
33                 size_t len = strcspn(src, "'!");
34                 strbuf_add(dst, src, len);
35                 src += len;
36                 while (need_bs_quote(*src)) {
37                         strbuf_addstr(dst, "'\\");
38                         strbuf_addch(dst, *src++);
39                         strbuf_addch(dst, '\'');
40                 }
41         }
42         strbuf_addch(dst, '\'');
43         free(to_free);
44 }
45
46 void sq_quote_buf_pretty(struct strbuf *dst, const char *src)
47 {
48         static const char ok_punct[] = "+,-./:=@_^";
49         const char *p;
50
51         for (p = src; *p; p++) {
52                 if (!isalpha(*p) && !isdigit(*p) && !strchr(ok_punct, *p)) {
53                         sq_quote_buf(dst, src);
54                         return;
55                 }
56         }
57
58         /* if we get here, we did not need quoting */
59         strbuf_addstr(dst, src);
60 }
61
62 void sq_quotef(struct strbuf *dst, const char *fmt, ...)
63 {
64         struct strbuf src = STRBUF_INIT;
65
66         va_list ap;
67         va_start(ap, fmt);
68         strbuf_vaddf(&src, fmt, ap);
69         va_end(ap);
70
71         sq_quote_buf(dst, src.buf);
72         strbuf_release(&src);
73 }
74
75 void sq_quote_argv(struct strbuf *dst, const char **argv)
76 {
77         int i;
78
79         /* Copy into destination buffer. */
80         strbuf_grow(dst, 255);
81         for (i = 0; argv[i]; ++i) {
82                 strbuf_addch(dst, ' ');
83                 sq_quote_buf(dst, argv[i]);
84         }
85 }
86
87 /*
88  * Legacy function to append each argv value, quoted as necessasry,
89  * with whitespace before each value.  This results in a leading
90  * space in the result.
91  */
92 void sq_quote_argv_pretty(struct strbuf *dst, const char **argv)
93 {
94         if (argv[0])
95                 strbuf_addch(dst, ' ');
96         sq_append_quote_argv_pretty(dst, argv);
97 }
98
99 /*
100  * Append each argv value, quoted as necessary, with whitespace between them.
101  */
102 void sq_append_quote_argv_pretty(struct strbuf *dst, const char **argv)
103 {
104         int i;
105
106         for (i = 0; argv[i]; i++) {
107                 if (i > 0)
108                         strbuf_addch(dst, ' ');
109                 sq_quote_buf_pretty(dst, argv[i]);
110         }
111 }
112
113 static char *sq_dequote_step(char *arg, char **next)
114 {
115         char *dst = arg;
116         char *src = arg;
117         char c;
118
119         if (*src != '\'')
120                 return NULL;
121         for (;;) {
122                 c = *++src;
123                 if (!c)
124                         return NULL;
125                 if (c != '\'') {
126                         *dst++ = c;
127                         continue;
128                 }
129                 /* We stepped out of sq */
130                 switch (*++src) {
131                 case '\0':
132                         *dst = 0;
133                         if (next)
134                                 *next = NULL;
135                         return arg;
136                 case '\\':
137                         /*
138                          * Allow backslashed characters outside of
139                          * single-quotes only if they need escaping,
140                          * and only if we resume the single-quoted part
141                          * afterward.
142                          */
143                         if (need_bs_quote(src[1]) && src[2] == '\'') {
144                                 *dst++ = src[1];
145                                 src += 2;
146                                 continue;
147                         }
148                 /* Fallthrough */
149                 default:
150                         if (!next || !isspace(*src))
151                                 return NULL;
152                         do {
153                                 c = *++src;
154                         } while (isspace(c));
155                         *dst = 0;
156                         *next = src;
157                         return arg;
158                 }
159         }
160 }
161
162 char *sq_dequote(char *arg)
163 {
164         return sq_dequote_step(arg, NULL);
165 }
166
167 static int sq_dequote_to_argv_internal(char *arg,
168                                        const char ***argv, int *nr, int *alloc,
169                                        struct argv_array *array)
170 {
171         char *next = arg;
172
173         if (!*arg)
174                 return 0;
175         do {
176                 char *dequoted = sq_dequote_step(next, &next);
177                 if (!dequoted)
178                         return -1;
179                 if (argv) {
180                         ALLOC_GROW(*argv, *nr + 1, *alloc);
181                         (*argv)[(*nr)++] = dequoted;
182                 }
183                 if (array)
184                         argv_array_push(array, dequoted);
185         } while (next);
186
187         return 0;
188 }
189
190 int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc)
191 {
192         return sq_dequote_to_argv_internal(arg, argv, nr, alloc, NULL);
193 }
194
195 int sq_dequote_to_argv_array(char *arg, struct argv_array *array)
196 {
197         return sq_dequote_to_argv_internal(arg, NULL, NULL, NULL, array);
198 }
199
200 /* 1 means: quote as octal
201  * 0 means: quote as octal if (quote_path_fully)
202  * -1 means: never quote
203  * c: quote as "\\c"
204  */
205 #define X8(x)   x, x, x, x, x, x, x, x
206 #define X16(x)  X8(x), X8(x)
207 static signed char const sq_lookup[256] = {
208         /*           0    1    2    3    4    5    6    7 */
209         /* 0x00 */   1,   1,   1,   1,   1,   1,   1, 'a',
210         /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r',   1,   1,
211         /* 0x10 */ X16(1),
212         /* 0x20 */  -1,  -1, '"',  -1,  -1,  -1,  -1,  -1,
213         /* 0x28 */ X16(-1), X16(-1), X16(-1),
214         /* 0x58 */  -1,  -1,  -1,  -1,'\\',  -1,  -1,  -1,
215         /* 0x60 */ X16(-1), X8(-1),
216         /* 0x78 */  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,
217         /* 0x80 */ /* set to 0 */
218 };
219
220 static inline int sq_must_quote(char c)
221 {
222         return sq_lookup[(unsigned char)c] + quote_path_fully > 0;
223 }
224
225 /* returns the longest prefix not needing a quote up to maxlen if positive.
226    This stops at the first \0 because it's marked as a character needing an
227    escape */
228 static size_t next_quote_pos(const char *s, ssize_t maxlen)
229 {
230         size_t len;
231         if (maxlen < 0) {
232                 for (len = 0; !sq_must_quote(s[len]); len++);
233         } else {
234                 for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++);
235         }
236         return len;
237 }
238
239 /*
240  * C-style name quoting.
241  *
242  * (1) if sb and fp are both NULL, inspect the input name and counts the
243  *     number of bytes that are needed to hold c_style quoted version of name,
244  *     counting the double quotes around it but not terminating NUL, and
245  *     returns it.
246  *     However, if name does not need c_style quoting, it returns 0.
247  *
248  * (2) if sb or fp are not NULL, it emits the c_style quoted version
249  *     of name, enclosed with double quotes if asked and needed only.
250  *     Return value is the same as in (1).
251  */
252 static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
253                                     struct strbuf *sb, FILE *fp, int no_dq)
254 {
255 #undef EMIT
256 #define EMIT(c)                                 \
257         do {                                        \
258                 if (sb) strbuf_addch(sb, (c));          \
259                 if (fp) fputc((c), fp);                 \
260                 count++;                                \
261         } while (0)
262 #define EMITBUF(s, l)                           \
263         do {                                        \
264                 if (sb) strbuf_add(sb, (s), (l));       \
265                 if (fp) fwrite((s), (l), 1, fp);        \
266                 count += (l);                           \
267         } while (0)
268
269         size_t len, count = 0;
270         const char *p = name;
271
272         for (;;) {
273                 int ch;
274
275                 len = next_quote_pos(p, maxlen);
276                 if (len == maxlen || (maxlen < 0 && !p[len]))
277                         break;
278
279                 if (!no_dq && p == name)
280                         EMIT('"');
281
282                 EMITBUF(p, len);
283                 EMIT('\\');
284                 p += len;
285                 ch = (unsigned char)*p++;
286                 if (maxlen >= 0)
287                         maxlen -= len + 1;
288                 if (sq_lookup[ch] >= ' ') {
289                         EMIT(sq_lookup[ch]);
290                 } else {
291                         EMIT(((ch >> 6) & 03) + '0');
292                         EMIT(((ch >> 3) & 07) + '0');
293                         EMIT(((ch >> 0) & 07) + '0');
294                 }
295         }
296
297         EMITBUF(p, len);
298         if (p == name)   /* no ending quote needed */
299                 return 0;
300
301         if (!no_dq)
302                 EMIT('"');
303         return count;
304 }
305
306 size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq)
307 {
308         return quote_c_style_counted(name, -1, sb, fp, nodq);
309 }
310
311 void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq)
312 {
313         if (quote_c_style(prefix, NULL, NULL, 0) ||
314             quote_c_style(path, NULL, NULL, 0)) {
315                 if (!nodq)
316                         strbuf_addch(sb, '"');
317                 quote_c_style(prefix, sb, NULL, 1);
318                 quote_c_style(path, sb, NULL, 1);
319                 if (!nodq)
320                         strbuf_addch(sb, '"');
321         } else {
322                 strbuf_addstr(sb, prefix);
323                 strbuf_addstr(sb, path);
324         }
325 }
326
327 void write_name_quoted(const char *name, FILE *fp, int terminator)
328 {
329         if (terminator) {
330                 quote_c_style(name, NULL, fp, 0);
331         } else {
332                 fputs(name, fp);
333         }
334         fputc(terminator, fp);
335 }
336
337 void write_name_quoted_relative(const char *name, const char *prefix,
338                                 FILE *fp, int terminator)
339 {
340         struct strbuf sb = STRBUF_INIT;
341
342         name = relative_path(name, prefix, &sb);
343         write_name_quoted(name, fp, terminator);
344
345         strbuf_release(&sb);
346 }
347
348 /* quote path as relative to the given prefix */
349 char *quote_path_relative(const char *in, const char *prefix,
350                           struct strbuf *out)
351 {
352         struct strbuf sb = STRBUF_INIT;
353         const char *rel = relative_path(in, prefix, &sb);
354         strbuf_reset(out);
355         quote_c_style_counted(rel, strlen(rel), out, NULL, 0);
356         strbuf_release(&sb);
357
358         return out->buf;
359 }
360
361 /*
362  * C-style name unquoting.
363  *
364  * Quoted should point at the opening double quote.
365  * + Returns 0 if it was able to unquote the string properly, and appends the
366  *   result in the strbuf `sb'.
367  * + Returns -1 in case of error, and doesn't touch the strbuf. Though note
368  *   that this function will allocate memory in the strbuf, so calling
369  *   strbuf_release is mandatory whichever result unquote_c_style returns.
370  *
371  * Updates endp pointer to point at one past the ending double quote if given.
372  */
373 int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
374 {
375         size_t oldlen = sb->len, len;
376         int ch, ac;
377
378         if (*quoted++ != '"')
379                 return -1;
380
381         for (;;) {
382                 len = strcspn(quoted, "\"\\");
383                 strbuf_add(sb, quoted, len);
384                 quoted += len;
385
386                 switch (*quoted++) {
387                   case '"':
388                         if (endp)
389                                 *endp = quoted;
390                         return 0;
391                   case '\\':
392                         break;
393                   default:
394                         goto error;
395                 }
396
397                 switch ((ch = *quoted++)) {
398                 case 'a': ch = '\a'; break;
399                 case 'b': ch = '\b'; break;
400                 case 'f': ch = '\f'; break;
401                 case 'n': ch = '\n'; break;
402                 case 'r': ch = '\r'; break;
403                 case 't': ch = '\t'; break;
404                 case 'v': ch = '\v'; break;
405
406                 case '\\': case '"':
407                         break; /* verbatim */
408
409                 /* octal values with first digit over 4 overflow */
410                 case '0': case '1': case '2': case '3':
411                                         ac = ((ch - '0') << 6);
412                         if ((ch = *quoted++) < '0' || '7' < ch)
413                                 goto error;
414                                         ac |= ((ch - '0') << 3);
415                         if ((ch = *quoted++) < '0' || '7' < ch)
416                                 goto error;
417                                         ac |= (ch - '0');
418                                         ch = ac;
419                                         break;
420                                 default:
421                         goto error;
422                         }
423                 strbuf_addch(sb, ch);
424                 }
425
426   error:
427         strbuf_setlen(sb, oldlen);
428         return -1;
429 }
430
431 /* quoting as a string literal for other languages */
432
433 void perl_quote_buf(struct strbuf *sb, const char *src)
434 {
435         const char sq = '\'';
436         const char bq = '\\';
437         char c;
438
439         strbuf_addch(sb, sq);
440         while ((c = *src++)) {
441                 if (c == sq || c == bq)
442                         strbuf_addch(sb, bq);
443                 strbuf_addch(sb, c);
444         }
445         strbuf_addch(sb, sq);
446 }
447
448 void python_quote_buf(struct strbuf *sb, const char *src)
449 {
450         const char sq = '\'';
451         const char bq = '\\';
452         const char nl = '\n';
453         char c;
454
455         strbuf_addch(sb, sq);
456         while ((c = *src++)) {
457                 if (c == nl) {
458                         strbuf_addch(sb, bq);
459                         strbuf_addch(sb, 'n');
460                         continue;
461                 }
462                 if (c == sq || c == bq)
463                         strbuf_addch(sb, bq);
464                 strbuf_addch(sb, c);
465         }
466         strbuf_addch(sb, sq);
467 }
468
469 void tcl_quote_buf(struct strbuf *sb, const char *src)
470 {
471         char c;
472
473         strbuf_addch(sb, '"');
474         while ((c = *src++)) {
475                 switch (c) {
476                 case '[': case ']':
477                 case '{': case '}':
478                 case '$': case '\\': case '"':
479                         strbuf_addch(sb, '\\');
480                         /* fallthrough */
481                 default:
482                         strbuf_addch(sb, c);
483                         break;
484                 case '\f':
485                         strbuf_addstr(sb, "\\f");
486                         break;
487                 case '\r':
488                         strbuf_addstr(sb, "\\r");
489                         break;
490                 case '\n':
491                         strbuf_addstr(sb, "\\n");
492                         break;
493                 case '\t':
494                         strbuf_addstr(sb, "\\t");
495                         break;
496                 case '\v':
497                         strbuf_addstr(sb, "\\v");
498                         break;
499                 }
500         }
501         strbuf_addch(sb, '"');
502 }
503
504 void basic_regex_quote_buf(struct strbuf *sb, const char *src)
505 {
506         char c;
507
508         if (*src == '^') {
509                 /* only beginning '^' is special and needs quoting */
510                 strbuf_addch(sb, '\\');
511                 strbuf_addch(sb, *src++);
512         }
513         if (*src == '*')
514                 /* beginning '*' is not special, no quoting */
515                 strbuf_addch(sb, *src++);
516
517         while ((c = *src++)) {
518                 switch (c) {
519                 case '[':
520                 case '.':
521                 case '\\':
522                 case '*':
523                         strbuf_addch(sb, '\\');
524                         strbuf_addch(sb, c);
525                         break;
526
527                 case '$':
528                         /* only the end '$' is special and needs quoting */
529                         if (*src == '\0')
530                                 strbuf_addch(sb, '\\');
531                         strbuf_addch(sb, c);
532                         break;
533
534                 default:
535                         strbuf_addch(sb, c);
536                         break;
537                 }
538         }
539 }