@@ -98,12 +98,57 @@ std::vector<std::string> split(const std::string& s, const std::string& delim) {
9898 return elems;
9999}
100100
101+ static
102+ std::string
103+ replaceSubstring (const std::string& in, const std::string& substring, const std::string& replaceWith) {
104+ std::string output = in;
105+ size_t index = 0 ;
106+
107+ if (substring.empty ())
108+ return output;
109+
110+ for (;;) {
111+ index = output.find (substring, index);
112+ if (index == std::string::npos) break ;
113+ output.replace (index, substring.size (), replaceWith);
114+ }
115+
116+ return output;
117+ }
118+
119+ static
120+ std::string
121+ replaceSubstringWithinDelimiters (const std::string& str, const std::string& sub, const std::string& rep, const std::string& delim){
122+ std::string output = str;
123+ if (delim.empty () || sub.empty ())
124+ return output;
125+
126+ size_t startDelim = output.find (delim, 0 );
127+ while (startDelim != std::string::npos){
128+ size_t endDelim = output.find (delim, startDelim+1 );
129+ if (endDelim == std::string::npos)
130+ break ;
131+
132+ size_t posSub = output.find (sub, startDelim);
133+ while (posSub != std::string::npos && posSub < endDelim){
134+ output.replace (output.begin () + posSub, output.begin () + posSub + sub.size (), rep);
135+
136+ endDelim = output.find (delim, startDelim+1 );
137+ posSub = output.find (sub, startDelim);
138+ }
139+
140+ startDelim = output.find (delim, endDelim+1 );
141+ }
142+
143+ return output;
144+ }
101145
102146static
103147inline
104148std::vector<std::string> splitQuotedString (const std::string &in, std::string delimiter) {
149+ auto inproxy = replaceSubstringWithinDelimiters (in, " " , " $%SPA&^CE!%" , " \" " );
105150 std::vector<std::string> items;
106- std::vector<std::string> items_delim = split (in , delimiter);
151+ std::vector<std::string> items_delim = split (inproxy , delimiter);
107152
108153 std::string cur_item;
109154 for (auto i : items_delim)
@@ -142,6 +187,10 @@ std::vector<std::string> splitQuotedString(const std::string &in, std::string de
142187 cur_item.clear ();
143188 }
144189
190+ for (auto & x : items) {
191+ x = replaceSubstring (x, " $%SPA&^CE!%" , " " );
192+ }
193+
145194 return items;
146195}
147196
@@ -159,11 +208,11 @@ std::string& trim(std::string& s, const char* t = "\"\n\t ")
159208static
160209bool isStringMultibyte (const std::string& str)
161210{
162- for (unsigned int i = 0 ; i < str.size (); i++) {
163- if ((0x80 & str[i]) != 0 )
164- return true ;
165- }
166- return false ;
211+ for (unsigned int i = 0 ; i < str.size (); i++) {
212+ if ((0x80 & str[i]) != 0 )
213+ return true ;
214+ }
215+ return false ;
167216}
168217#endif
169218
@@ -187,7 +236,23 @@ system_call_status_t startProcess(std::string command, std::string logfile, Proc
187236 sa.lpSecurityDescriptor = NULL ;
188237 sa.bInheritHandle = TRUE ;
189238
190- log_handle = CreateFile (logfile.c_str (),
239+ LPWSTR logfile_wide = NULL ;
240+ if (isStringMultibyte (logfile) == false ) {
241+ std::wstring_convert<std::codecvt_utf8<wchar_t >> myconv;
242+ std::wstring wide_str = myconv.from_bytes (logfile);
243+ wide_str.push_back (NULL ); // need to manually null-terminate the string
244+ logfile_wide = new WCHAR[wide_str.length ()];
245+ memcpy (logfile_wide, wide_str.c_str (), wide_str.length () * sizeof (wchar_t ));
246+ }
247+ else {
248+ int wideLength = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, logfile.c_str (), (int )logfile.size () + 1 , logfile_wide, 0 );
249+ if (wideLength != 0 ) {
250+ logfile_wide = new WCHAR[wideLength];
251+ MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, logfile.c_str (), (int )logfile.size () + 1 , logfile_wide, wideLength);
252+ }
253+ }
254+
255+ log_handle = CreateFileW (logfile_wide,
191256 FILE_APPEND_DATA,
192257 FILE_SHARE_WRITE | FILE_SHARE_READ,
193258 &sa,
@@ -199,34 +264,35 @@ system_call_status_t startProcess(std::string command, std::string logfile, Proc
199264 processData.startupInfo .hStdInput = NULL ;
200265 processData.startupInfo .hStdOutput = log_handle;
201266 processData.startupInfo .hStdError = log_handle;
267+
268+ if (logfile_wide != NULL )
269+ delete [] logfile_wide;
270+ }
271+
272+ LPWSTR command_line_wide = NULL ;
273+ if (isStringMultibyte (command_line) == false ) {
274+ std::wstring_convert<std::codecvt_utf8<wchar_t >> myconv;
275+ std::wstring wide_str = myconv.from_bytes (command_line);
276+ wide_str.push_back (NULL ); // need to manually null-terminate the string
277+ command_line_wide = new WCHAR[wide_str.length ()];
278+ memcpy (command_line_wide, wide_str.c_str (), wide_str.length () * sizeof (wchar_t ));
279+ }
280+ else {
281+ int wideLength = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, command_line.c_str (), (int )command_line.size () + 1 , command_line_wide, 0 );
282+ if (wideLength != 0 ) {
283+ command_line_wide = new WCHAR[wideLength];
284+ MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, command_line.c_str (), (int )command_line.size () + 1 , command_line_wide, wideLength);
285+ }
202286 }
203287
204- LPWSTR command_line_wide = NULL ;
205- int wideLength;
206-
207- if (isStringMultibyte (command_line) == false ) {
208- std::wstring_convert<std::codecvt_utf8<wchar_t >> myconv;
209- std::wstring wide_str = myconv.from_bytes (command_line);
210- wide_str.push_back (NULL ); // need to manually null-terminate the string
211- command_line_wide = new WCHAR[wide_str.length ()];
212- memcpy (command_line_wide, wide_str.c_str (), wide_str.length () * sizeof (wchar_t ));
213- }
214- else {
215- wideLength = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, command_line.c_str (), (int )command_line.size () + 1 , command_line_wide, 0 );
216- if (wideLength != 0 ) {
217- command_line_wide = new WCHAR[wideLength];
218- MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, command_line.c_str (), (int )command_line.size () + 1 , command_line_wide, wideLength);
219- }
220- }
221-
222288 BOOL status = CreateProcessW (NULL , command_line_wide, NULL , NULL , TRUE , 0 , NULL , NULL , &processData.startupInfo , &processData.processInfo );
223289 // closing unneeded handles
224290 CloseHandle (processData.processInfo .hThread );
225291 CloseHandle (processData.startupInfo .hStdInput );
226292 CloseHandle (log_handle);
227- if (command_line_wide != NULL )
228- delete[] command_line_wide;
229-
293+ if (command_line_wide != NULL )
294+ delete[] command_line_wide;
295+
230296 if (status == 0 ) {
231297 return SYSCALL_STATUS_CALL_ERROR;
232298 }
0 commit comments