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