ref-filter: align: introduce long-form syntax
[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_argv(struct strbuf *dst, const char** argv, size_t maxlen)
47 {
48         int i;
49
50         /* Copy into destination buffer. */
51         strbuf_grow(dst, 255);
52         for (i = 0; argv[i]; ++i) {
53                 strbuf_addch(dst, ' ');
54                 sq_quote_buf(dst, argv[i]);
55                 if (maxlen && dst->len > maxlen)
56                         die("Too many or long arguments");
57         }
58 }
59
60 static char *sq_dequote_step(char *arg, char **next)
61 {
62         char *dst = arg;
63         char *src = arg;
64         char c;
65
66         if (*src != '\'')
67                 return NULL;
68         for (;;) {
69                 c = *++src;
70                 if (!c)
71                         return NULL;
72                 if (c != '\'') {
73                         *dst++ = c;
74                         continue;
75                 }
76                 /* We stepped out of sq */
77                 switch (*++src) {
78                 case '\0':
79                         *dst = 0;
80                         if (next)
81                                 *next = NULL;
82                         return arg;
83                 case '\\':
84                         c = *++src;
85                         if (need_bs_quote(c) && *++src == '\'') {
86                                 *dst++ = c;
87                                 continue;
88                         }
89                 /* Fallthrough */
90                 default:
91                         if (!next || !isspace(*src))
92                                 return NULL;
93                         do {
94                                 c = *++src;
95                         } while (isspace(c));
96                         *dst = 0;
97                         *next = src;
98                         return arg;
99                 }
100         }
101 }
102
103 char *sq_dequote(char *arg)
104 {
105         return sq_dequote_step(arg, NULL);
106 }
107
108 static int sq_dequote_to_argv_internal(char *arg,
109                                        const char ***argv, int *nr, int *alloc,
110                                        struct argv_array *array)
111 {
112         char *next = arg;
113
114         if (!*arg)
115                 return 0;
116         do {
117                 char *dequoted = sq_dequote_step(next, &next);
118                 if (!dequoted)
119                         return -1;
120                 if (argv) {
121                         ALLOC_GROW(*argv, *nr + 1, *alloc);
122                         (*argv)[(*nr)++] = dequoted;
123                 }
124                 if (array)
125                         argv_array_push(array, dequoted);
126         } while (next);
127
128         return 0;
129 }
130
131 int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc)
132 {
133         return sq_dequote_to_argv_internal(arg, argv, nr, alloc, NULL);
134 }
135
136 int sq_dequote_to_argv_array(char *arg, struct argv_array *array)
137 {
138         return sq_dequote_to_argv_internal(arg, NULL, NULL, NULL, array);
139 }
140
141 /* 1 means: quote as octal
142  * 0 means: quote as octal if (quote_path_fully)
143  * -1 means: never quote
144  * c: quote as "\\c"
145  */
146 #define X8(x)   x, x, x, x, x, x, x, x
147 #define X16(x)  X8(x), X8(x)
148 static signed char const sq_lookup[256] = {
149         /*           0    1    2    3    4    5    6    7 */
150         /* 0x00 */   1,   1,   1,   1,   1,   1,   1, 'a',
151         /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r',   1,   1,
152         /* 0x10 */ X16(1),
153         /* 0x20 */  -1,  -1, '"',  -1,  -1,  -1,  -1,  -1,
154         /* 0x28 */ X16(-1), X16(-1), X16(-1),
155         /* 0x58 */  -1,  -1,  -1,  -1,'\\',  -1,  -1,  -1,
156         /* 0x60 */ X16(-1), X8(-1),
157         /* 0x78 */  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,
158         /* 0x80 */ /* set to 0 */
159 };
160
161 static inline int sq_must_quote(char c)
162 {
163         return sq_lookup[(unsigned char)c] + quote_path_fully > 0;
164 }
165
166 /* returns the longest prefix not needing a quote up to maxlen if positive.
167    This stops at the first \0 because it's marked as a character needing an
168    escape */
169 static size_t next_quote_pos(const char *s, ssize_t maxlen)
170 {
171         size_t len;
172         if (maxlen < 0) {
173                 for (len = 0; !sq_must_quote(s[len]); len++);
174         } else {
175                 for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++);
176         }
177         return len;
178 }
179
180 /*
181  * C-style name quoting.
182  *
183  * (1) if sb and fp are both NULL, inspect the input name and counts the
184  *     number of bytes that are needed to hold c_style quoted version of name,
185  *     counting the double quotes around it but not terminating NUL, and
186  *     returns it.
187  *     However, if name does not need c_style quoting, it returns 0.
188  *
189  * (2) if sb or fp are not NULL, it emits the c_style quoted version
190  *     of name, enclosed with double quotes if asked and needed only.
191  *     Return value is the same as in (1).
192  */
193 static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
194                                     struct strbuf *sb, FILE *fp, int no_dq)
195 {
196 #undef EMIT
197 #define EMIT(c)                                 \
198         do {                                        \
199                 if (sb) strbuf_addch(sb, (c));          \
200                 if (fp) fputc((c), fp);                 \
201                 count++;                                \
202         } while (0)
203 #define EMITBUF(s, l)                           \
204         do {                                        \
205                 if (sb) strbuf_add(sb, (s), (l));       \
206                 if (fp) fwrite((s), (l), 1, fp);        \
207                 count += (l);                           \
208         } while (0)
209
210         size_t len, count = 0;
211         const char *p = name;
212
213         for (;;) {
214                 int ch;
215
216                 len = next_quote_pos(p, maxlen);
217                 if (len == maxlen || (maxlen < 0 && !p[len]))
218                         break;
219
220                 if (!no_dq && p == name)
221                         EMIT('"');
222
223                 EMITBUF(p, len);
224                 EMIT('\\');
225                 p += len;
226                 ch = (unsigned char)*p++;
227                 if (maxlen >= 0)
228                         maxlen -= len + 1;
229                 if (sq_lookup[ch] >= ' ') {
230                         EMIT(sq_lookup[ch]);
231                 } else {
232                         EMIT(((ch >> 6) & 03) + '0');
233                         EMIT(((ch >> 3) & 07) + '0');
234                         EMIT(((ch >> 0) & 07) + '0');
235                 }
236         }
237
238         EMITBUF(p, len);
239         if (p == name)   /* no ending quote needed */
240                 return 0;
241
242         if (!no_dq)
243                 EMIT('"');
244         return count;
245 }
246
247 size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq)
248 {
249         return quote_c_style_counted(name, -1, sb, fp, nodq);
250 }
251
252 void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq)
253 {
254         if (quote_c_style(prefix, NULL, NULL, 0) ||
255             quote_c_style(path, NULL, NULL, 0)) {
256                 if (!nodq)
257                         strbuf_addch(sb, '"');
258                 quote_c_style(prefix, sb, NULL, 1);
259                 quote_c_style(path, sb, NULL, 1);
260                 if (!nodq)
261                         strbuf_addch(sb, '"');
262         } else {
263                 strbuf_addstr(sb, prefix);
264                 strbuf_addstr(sb, path);
265         }
266 }
267
268 void write_name_quoted(const char *name, FILE *fp, int terminator)
269 {
270         if (terminator) {
271                 quote_c_style(name, NULL, fp, 0);
272         } else {
273                 fputs(name, fp);
274         }
275         fputc(terminator, fp);
276 }
277
278 void write_name_quoted_relative(const char *name, const char *prefix,
279                                 FILE *fp, int terminator)
280 {
281         struct strbuf sb = STRBUF_INIT;
282
283         name = relative_path(name, prefix, &sb);
284         write_name_quoted(name, fp, terminator);
285
286         strbuf_release(&sb);
287 }
288
289 /* quote path as relative to the given prefix */
290 char *quote_path_relative(const char *in, const char *prefix,
291                           struct strbuf *out)
292 {
293         struct strbuf sb = STRBUF_INIT;
294         const char *rel = relative_path(in, prefix, &sb);
295         strbuf_reset(out);
296         quote_c_style_counted(rel, strlen(rel), out, NULL, 0);
297         strbuf_release(&sb);
298
299         return out->buf;
300 }
301
302 /*
303  * C-style name unquoting.
304  *
305  * Quoted should point at the opening double quote.
306  * + Returns 0 if it was able to unquote the string properly, and appends the
307  *   result in the strbuf `sb'.
308  * + Returns -1 in case of error, and doesn't touch the strbuf. Though note
309  *   that this function will allocate memory in the strbuf, so calling
310  *   strbuf_release is mandatory whichever result unquote_c_style returns.
311  *
312  * Updates endp pointer to point at one past the ending double quote if given.
313  */
314 int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)
315 {
316         size_t oldlen = sb->len, len;
317         int ch, ac;
318
319         if (*quoted++ != '"')
320                 return -1;
321
322         for (;;) {
323                 len = strcspn(quoted, "\"\\");
324                 strbuf_add(sb, quoted, len);
325                 quoted += len;
326
327                 switch (*quoted++) {
328                   case '"':
329                         if (endp)
330                                 *endp = quoted;
331                         return 0;
332                   case '\\':
333                         break;
334                   default:
335                         goto error;
336                 }
337
338                 switch ((ch = *quoted++)) {
339                 case 'a': ch = '\a'; break;
340                 case 'b': ch = '\b'; break;
341                 case 'f': ch = '\f'; break;
342                 case 'n': ch = '\n'; break;
343                 case 'r': ch = '\r'; break;
344                 case 't': ch = '\t'; break;
345                 case 'v': ch = '\v'; break;
346
347                 case '\\': case '"':
348                         break; /* verbatim */
349
350                 /* octal values with first digit over 4 overflow */
351                 case '0': case '1': case '2': case '3':
352                                         ac = ((ch - '0') << 6);
353                         if ((ch = *quoted++) < '0' || '7' < ch)
354                                 goto error;
355                                         ac |= ((ch - '0') << 3);
356                         if ((ch = *quoted++) < '0' || '7' < ch)
357                                 goto error;
358                                         ac |= (ch - '0');
359                                         ch = ac;
360                                         break;
361                                 default:
362                         goto error;
363                         }
364                 strbuf_addch(sb, ch);
365                 }
366
367   error:
368         strbuf_setlen(sb, oldlen);
369         return -1;
370 }
371
372 /* quoting as a string literal for other languages */
373
374 void perl_quote_buf(struct strbuf *sb, const char *src)
375 {
376         const char sq = '\'';
377         const char bq = '\\';
378         char c;
379
380         strbuf_addch(sb, sq);
381         while ((c = *src++)) {
382                 if (c == sq || c == bq)
383                         strbuf_addch(sb, bq);
384                 strbuf_addch(sb, c);
385         }
386         strbuf_addch(sb, sq);
387 }
388
389 void python_quote_buf(struct strbuf *sb, const char *src)
390 {
391         const char sq = '\'';
392         const char bq = '\\';
393         const char nl = '\n';
394         char c;
395
396         strbuf_addch(sb, sq);
397         while ((c = *src++)) {
398                 if (c == nl) {
399                         strbuf_addch(sb, bq);
400                         strbuf_addch(sb, 'n');
401                         continue;
402                 }
403                 if (c == sq || c == bq)
404                         strbuf_addch(sb, bq);
405                 strbuf_addch(sb, c);
406         }
407         strbuf_addch(sb, sq);
408 }
409
410 void tcl_quote_buf(struct strbuf *sb, const char *src)
411 {
412         char c;
413
414         strbuf_addch(sb, '"');
415         while ((c = *src++)) {
416                 switch (c) {
417                 case '[': case ']':
418                 case '{': case '}':
419                 case '$': case '\\': case '"':
420                         strbuf_addch(sb, '\\');
421                 default:
422                         strbuf_addch(sb, c);
423                         break;
424                 case '\f':
425                         strbuf_addstr(sb, "\\f");
426                         break;
427                 case '\r':
428                         strbuf_addstr(sb, "\\r");
429                         break;
430                 case '\n':
431                         strbuf_addstr(sb, "\\n");
432                         break;
433                 case '\t':
434                         strbuf_addstr(sb, "\\t");
435                         break;
436                 case '\v':
437                         strbuf_addstr(sb, "\\v");
438                         break;
439                 }
440         }
441         strbuf_addch(sb, '"');
442 }