@@ -55,17 +55,44 @@ extern void catFile (MIO *mio)
55
55
# define PE_CONST const
56
56
#endif
57
57
58
+ /*
59
+ Output file name should not be evaluated in system(3) function.
60
+ The name must be used as is. Quotations are required to block the
61
+ evaluation.
62
+
63
+ Normal single-quotes are used to quote a cstring:
64
+ a => 'a'
65
+ " => '"'
66
+
67
+ If a single-quote is included in the cstring, use double quotes for quoting it.
68
+ ' => ''"'"''
69
+ */
70
+ static void appendCstringWithQuotes (vString * dest , const char * cstr )
71
+ {
72
+ const char * o ;
73
+
74
+ vStringPut (dest , '\'' );
75
+ for (o = cstr ; * o ; o ++ )
76
+ {
77
+ if (* o == '\'' )
78
+ vStringCatS (dest , "'\"'\"'" );
79
+ else
80
+ vStringPut (dest , * o );
81
+ }
82
+ vStringPut (dest , '\'' );
83
+ }
84
+
58
85
extern void externalSortTags (const bool toStdout , MIO * tagFile )
59
86
{
60
87
const char * const sortNormalCommand = "sort -u" ;
61
88
const char * const sortFoldedCommand = "sort -u -f" ;
62
89
const char * sortCommand =
63
90
Option .sorted == SO_FOLDSORTED ? sortFoldedCommand : sortNormalCommand ;
91
+ # ifndef HAVE_SETENV
64
92
PE_CONST char * const sortOrder1 = "LC_COLLATE=C" ;
65
93
PE_CONST char * const sortOrder2 = "LC_ALL=C" ;
66
- const size_t length = 4 + strlen (sortOrder1 ) + strlen (sortOrder2 ) +
67
- strlen (sortCommand ) + (2 * strlen (tagFileName ()));
68
- char * const cmd = (char * ) malloc (length + 1 );
94
+ # endif
95
+ vString * cmd = vStringNew ();
69
96
int ret = -1 ;
70
97
71
98
if (cmd != NULL )
@@ -80,19 +107,29 @@ extern void externalSortTags (const bool toStdout, MIO *tagFile)
80
107
putenv (sortOrder1 );
81
108
putenv (sortOrder2 );
82
109
# endif
83
- if (toStdout )
84
- sprintf (cmd , "%s" , sortCommand );
85
- else
86
- sprintf (cmd , "%s -o %s %s" , sortCommand ,
87
- tagFileName (), tagFileName ());
110
+ vStringCatS (cmd , sortCommand );
111
+ if (! toStdout )
112
+ {
113
+ vStringCatS (cmd , " -o " );
114
+ appendCstringWithQuotes (cmd , tagFileName ());
115
+ vStringPut (cmd , ' ' );
116
+ appendCstringWithQuotes (cmd , tagFileName ());
117
+ }
88
118
#else
89
- if (toStdout )
90
- sprintf (cmd , "%s %s %s" , sortOrder1 , sortOrder2 , sortCommand );
91
- else
92
- sprintf (cmd , "%s %s %s -o %s %s" , sortOrder1 , sortOrder2 ,
93
- sortCommand , tagFileName (), tagFileName ());
119
+ vStringCatS (cmd , sortOrder1 );
120
+ vStringPut (cmd , ' ' );
121
+ vStringCatS (cmd , sortOrder2 );
122
+ vStringPut (cmd , ' ' );
123
+ vStringCatS (cmd , sortCommand );
124
+ if (! toStdout )
125
+ {
126
+ vStringCats (cmd , " -o " );
127
+ appendCstringWithQuotes (cmd , tagFileName ());
128
+ vStringPut (cmd , ' ' );
129
+ appendCstringWithQuotes (cmd , tagFileName ());
130
+ }
94
131
#endif
95
- verbose ("system (\"%s\")\n" , cmd );
132
+ verbose ("system (\"%s\")\n" , vStringValue ( cmd ) );
96
133
if (toStdout )
97
134
{
98
135
const int fdstdin = 0 ;
@@ -105,15 +142,14 @@ extern void externalSortTags (const bool toStdout, MIO *tagFile)
105
142
error (FATAL | PERROR , "cannot redirect stdin" );
106
143
if (lseek (fdstdin , 0 , SEEK_SET ) != 0 )
107
144
error (FATAL | PERROR , "cannot rewind tag file" );
108
- ret = system (cmd );
145
+ ret = system (vStringValue ( cmd ) );
109
146
if (dup2 (fdsave , fdstdin ) < 0 )
110
147
error (FATAL | PERROR , "cannot restore stdin fd" );
111
148
close (fdsave );
112
149
}
113
150
else
114
- ret = system (cmd );
115
- free (cmd );
116
-
151
+ ret = system (vStringValue (cmd ));
152
+ vStringDelete (cmd );
117
153
}
118
154
if (ret != 0 )
119
155
error (FATAL | PERROR , "cannot sort tag file" );
0 commit comments