2016-07-07 17:17:38 +03:00
# include <stdlib.h>
# include "strbuf.h"
2009-04-20 17:00:56 +04:00
# include "quote.h"
2016-07-07 17:17:38 +03:00
# include "util.h"
2009-04-20 17:00:56 +04:00
/* 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 = = ' ! ' ) ;
}
2016-05-10 08:47:26 +03:00
static int sq_quote_buf ( struct strbuf * dst , const char * src )
2009-04-20 17:00:56 +04:00
{
char * to_free = NULL ;
2016-05-10 08:47:26 +03:00
int ret ;
2009-04-20 17:00:56 +04:00
if ( dst - > buf = = src )
to_free = strbuf_detach ( dst , NULL ) ;
2016-05-10 08:47:26 +03:00
ret = strbuf_addch ( dst , ' \' ' ) ;
while ( ! ret & & * src ) {
2009-04-20 17:00:56 +04:00
size_t len = strcspn ( src , " '! " ) ;
2016-05-10 08:47:26 +03:00
ret = strbuf_add ( dst , src , len ) ;
2009-04-20 17:00:56 +04:00
src + = len ;
2016-05-10 08:47:26 +03:00
while ( ! ret & & need_bs_quote ( * src ) )
ret = strbuf_addf ( dst , " ' \\ %c \' " , * src + + ) ;
2009-04-20 17:00:56 +04:00
}
2016-05-10 08:47:26 +03:00
if ( ! ret )
ret = strbuf_addch ( dst , ' \' ' ) ;
2009-04-20 17:00:56 +04:00
free ( to_free ) ;
2016-05-10 08:47:26 +03:00
return ret ;
2009-04-20 17:00:56 +04:00
}
2016-05-10 08:47:26 +03:00
int sq_quote_argv ( struct strbuf * dst , const char * * argv , size_t maxlen )
2009-04-20 17:00:56 +04:00
{
2016-05-10 08:47:26 +03:00
int i , ret ;
2009-04-20 17:00:56 +04:00
/* Copy into destination buffer. */
2016-05-10 08:47:26 +03:00
ret = strbuf_grow ( dst , 255 ) ;
for ( i = 0 ; ! ret & & argv [ i ] ; + + i ) {
ret = strbuf_addch ( dst , ' ' ) ;
if ( ret )
break ;
ret = sq_quote_buf ( dst , argv [ i ] ) ;
2009-04-20 17:00:56 +04:00
if ( maxlen & & dst - > len > maxlen )
die ( " Too many or long arguments " ) ;
}
2016-05-10 08:47:26 +03:00
return ret ;
2009-04-20 17:00:56 +04:00
}