@@ -401,6 +401,7 @@ static void invalidate_nodes (fdesc *, node **);
401401static void put_entries (node * );
402402static void cleanup_tags_file (char const * const , char const * const );
403403
404+ static char * escape_shell_arg_string (char * );
404405static void do_move_file (const char * , const char * );
405406static char * concat (const char * , const char * , const char * );
406407static char * skip_spaces (char * );
@@ -1713,13 +1714,16 @@ process_file_name (char *file, language *lang)
17131714 else
17141715 {
17151716#if MSDOS || defined (DOS_NT )
1716- char * cmd1 = concat (compr -> command , " \"" , real_name );
1717- char * cmd = concat (cmd1 , "\" > " , tmp_name );
1717+ int buf_len = strlen (compr -> command ) + strlen (" \"\" > \"\"" ) + strlen (real_name ) + strlen (tmp_name ) + 1 ;
1718+ char * cmd = xmalloc (buf_len );
1719+ snprintf (cmd , buf_len , "%s \"%s\" > \"%s\"" , compr -> command , real_name , tmp_name );
17181720#else
1719- char * cmd1 = concat (compr -> command , " '" , real_name );
1720- char * cmd = concat (cmd1 , "' > " , tmp_name );
1721+ char * new_real_name = escape_shell_arg_string (real_name );
1722+ char * new_tmp_name = escape_shell_arg_string (tmp_name );
1723+ int buf_len = strlen (compr -> command ) + strlen (" > " ) + strlen (new_real_name ) + strlen (new_tmp_name ) + 1 ;
1724+ char * cmd = xmalloc (buf_len );
1725+ snprintf (cmd , buf_len , "%s %s > %s" , compr -> command , new_real_name , new_tmp_name );
17211726#endif
1722- free (cmd1 );
17231727 inf = (system (cmd ) == -1
17241728 ? NULL
17251729 : fopen (tmp_name , "r" FOPEN_BINARY ));
@@ -7707,6 +7711,55 @@ etags_mktmp (void)
77077711 return templt ;
77087712}
77097713
7714+ /*
7715+ * Adds single quotes around a string, if found single quotes, escaped it.
7716+ * Return a newly-allocated string.
7717+ *
7718+ * For example:
7719+ * escape_shell_arg_string("test.txt") => 'test.txt'
7720+ * escape_shell_arg_string("'test.txt") => ''\''test.txt'
7721+ */
7722+ static char *
7723+ escape_shell_arg_string (char * str )
7724+ {
7725+ char * p = str ;
7726+ int need_space = 2 ; /* ' at begin and end */
7727+
7728+ while (* p != '\0' )
7729+ {
7730+ if (* p == '\'' )
7731+ need_space += 4 ; /* ' to '\'', length is 4 */
7732+ else
7733+ need_space ++ ;
7734+
7735+ p ++ ;
7736+ }
7737+
7738+ char * new_str = xnew (need_space + 1 , char );
7739+ new_str [0 ] = '\'' ;
7740+ new_str [need_space - 1 ] = '\'' ;
7741+
7742+ int i = 1 ; /* skip first byte */
7743+ p = str ;
7744+ while (* p != '\0' )
7745+ {
7746+ new_str [i ] = * p ;
7747+ if (* p == '\'' )
7748+ {
7749+ new_str [i + 1 ] = '\\' ;
7750+ new_str [i + 2 ] = '\'' ;
7751+ new_str [i + 3 ] = '\'' ;
7752+ i += 3 ;
7753+ }
7754+
7755+ i ++ ;
7756+ p ++ ;
7757+ }
7758+
7759+ new_str [need_space ] = '\0' ;
7760+ return new_str ;
7761+ }
7762+
77107763static void
77117764do_move_file (const char * src_file , const char * dst_file )
77127765{
0 commit comments