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