at v4.11-rc3 60 lines 1.4 kB view raw
1#include <stdlib.h> 2#include "strbuf.h" 3#include "quote.h" 4#include "util.h" 5 6/* Help to copy the thing properly quoted for the shell safety. 7 * any single quote is replaced with '\'', any exclamation point 8 * is replaced with '\!', and the whole thing is enclosed in a 9 * 10 * E.g. 11 * original sq_quote result 12 * name ==> name ==> 'name' 13 * a b ==> a b ==> 'a b' 14 * a'b ==> a'\''b ==> 'a'\''b' 15 * a!b ==> a'\!'b ==> 'a'\!'b' 16 */ 17static inline int need_bs_quote(char c) 18{ 19 return (c == '\'' || c == '!'); 20} 21 22static int sq_quote_buf(struct strbuf *dst, const char *src) 23{ 24 char *to_free = NULL; 25 int ret; 26 27 if (dst->buf == src) 28 to_free = strbuf_detach(dst, NULL); 29 30 ret = strbuf_addch(dst, '\''); 31 while (!ret && *src) { 32 size_t len = strcspn(src, "'!"); 33 ret = strbuf_add(dst, src, len); 34 src += len; 35 while (!ret && need_bs_quote(*src)) 36 ret = strbuf_addf(dst, "'\\%c\'", *src++); 37 } 38 if (!ret) 39 ret = strbuf_addch(dst, '\''); 40 free(to_free); 41 42 return ret; 43} 44 45int sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) 46{ 47 int i, ret; 48 49 /* Copy into destination buffer. */ 50 ret = strbuf_grow(dst, 255); 51 for (i = 0; !ret && argv[i]; ++i) { 52 ret = strbuf_addch(dst, ' '); 53 if (ret) 54 break; 55 ret = sq_quote_buf(dst, argv[i]); 56 if (maxlen && dst->len > maxlen) 57 return -ENOSPC; 58 } 59 return ret; 60}