| 
									
										
										
										
											2009-04-20 15:00:56 +02:00
										 |  |  | #include "cache.h"
 | 
					
						
							|  |  |  | #include "quote.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Help to copy the thing properly quoted for the shell safety.
 | 
					
						
							|  |  |  |  * any single quote is replaced with '\'', any exclamation point | 
					
						
							|  |  |  |  * is replaced with '\!', and the whole thing is enclosed in a | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * E.g. | 
					
						
							|  |  |  |  *  original     sq_quote     result | 
					
						
							|  |  |  |  *  name     ==> name      ==> 'name' | 
					
						
							|  |  |  |  *  a b      ==> a b       ==> 'a b' | 
					
						
							|  |  |  |  *  a'b      ==> a'\''b    ==> 'a'\''b' | 
					
						
							|  |  |  |  *  a!b      ==> a'\!'b    ==> 'a'\!'b' | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int need_bs_quote(char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (c == '\'' || c == '!'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 18:29:23 -03:00
										 |  |  | static void sq_quote_buf(struct strbuf *dst, const char *src) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:00:56 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *to_free = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dst->buf == src) | 
					
						
							|  |  |  | 		to_free = strbuf_detach(dst, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	strbuf_addch(dst, '\''); | 
					
						
							|  |  |  | 	while (*src) { | 
					
						
							|  |  |  | 		size_t len = strcspn(src, "'!"); | 
					
						
							|  |  |  | 		strbuf_add(dst, src, len); | 
					
						
							|  |  |  | 		src += len; | 
					
						
							|  |  |  | 		while (need_bs_quote(*src)) { | 
					
						
							|  |  |  | 			strbuf_addstr(dst, "'\\"); | 
					
						
							|  |  |  | 			strbuf_addch(dst, *src++); | 
					
						
							|  |  |  | 			strbuf_addch(dst, '\''); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	strbuf_addch(dst, '\''); | 
					
						
							|  |  |  | 	free(to_free); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Copy into destination buffer. */ | 
					
						
							|  |  |  | 	strbuf_grow(dst, 255); | 
					
						
							|  |  |  | 	for (i = 0; argv[i]; ++i) { | 
					
						
							|  |  |  | 		strbuf_addch(dst, ' '); | 
					
						
							|  |  |  | 		sq_quote_buf(dst, argv[i]); | 
					
						
							|  |  |  | 		if (maxlen && dst->len > maxlen) | 
					
						
							|  |  |  | 			die("Too many or long arguments"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |