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 static inline int need_bs_quote(char c) 16 { 17 return (c == '\'' || c == '!'); 18 } 19 20 static void sq_quote_buf(struct strbuf *dst, const char *src) 21 { 22 char *to_free = NULL; 23 24 if (dst->buf == src) 25 to_free = strbuf_detach(dst, NULL); 26 27 strbuf_addch(dst, '\''); 28 while (*src) { 29 size_t len = strcspn(src, "'!"); 30 strbuf_add(dst, src, len); 31 src += len; 32 while (need_bs_quote(*src)) { 33 strbuf_addstr(dst, "'\\"); 34 strbuf_addch(dst, *src++); 35 strbuf_addch(dst, '\''); 36 } 37 } 38 strbuf_addch(dst, '\''); 39 free(to_free); 40 } 41 42 void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) 43 { 44 int i; 45 46 /* Copy into destination buffer. */ 47 strbuf_grow(dst, 255); 48 for (i = 0; argv[i]; ++i) { 49 strbuf_addch(dst, ' '); 50 sq_quote_buf(dst, argv[i]); 51 if (maxlen && dst->len > maxlen) 52 die("Too many or long arguments"); 53 } 54 } 55