@@ -401,6 +401,7 @@ static void invalidate_nodes (fdesc *, node **);
401
401
static void put_entries (node * );
402
402
static void cleanup_tags_file (char const * const , char const * const );
403
403
404
+ static char * escape_shell_arg_string (char * );
404
405
static void do_move_file (const char * , const char * );
405
406
static char * concat (const char * , const char * , const char * );
406
407
static char * skip_spaces (char * );
@@ -1713,13 +1714,16 @@ process_file_name (char *file, language *lang)
1713
1714
else
1714
1715
{
1715
1716
#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 );
1718
1720
#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 );
1721
1726
#endif
1722
- free (cmd1 );
1723
1727
inf = (system (cmd ) == -1
1724
1728
? NULL
1725
1729
: fopen (tmp_name , "r" FOPEN_BINARY ));
@@ -7707,6 +7711,55 @@ etags_mktmp (void)
7707
7711
return templt ;
7708
7712
}
7709
7713
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
+
7710
7763
static void
7711
7764
do_move_file (const char * src_file , const char * dst_file )
7712
7765
{
0 commit comments