Merge branch 'fixes'
[git] / quote.c
1 #include "cache.h"
2 #include "quote.h"
3
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
7  *
8  * E.g.
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'
14  */
15 #define EMIT(x) ( (++len < n) && (*bp++ = (x)) )
16
17 size_t sq_quote_buf(char *dst, size_t n, const char *src)
18 {
19         char c;
20         char *bp = dst;
21         size_t len = 0;
22
23         EMIT('\'');
24         while ((c = *src++)) {
25                 if (c == '\'' || c == '!') {
26                         EMIT('\'');
27                         EMIT('\\');
28                         EMIT(c);
29                         EMIT('\'');
30                 } else {
31                         EMIT(c);
32                 }
33         }
34         EMIT('\'');
35
36         if ( n )
37                 *bp = 0;
38
39         return len;
40 }
41
42 char *sq_quote(const char *src)
43 {
44         char *buf;
45         size_t cnt;
46
47         cnt = sq_quote_buf(NULL, 0, src) + 1;
48         buf = xmalloc(cnt);
49         sq_quote_buf(buf, cnt, src);
50
51         return buf;
52 }
53