[Windows] Add quotes only to the command line arguments with special characters.

(cherry picked from commit cac399a829)
This commit is contained in:
bruvzg 2020-05-19 16:34:15 +03:00 committed by Rémi Verschelde
parent 2c81a82d53
commit e3be0520a1
2 changed files with 29 additions and 20 deletions

View File

@ -2770,26 +2770,31 @@ void OS_Windows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent,
DeleteDC(hMainDC); DeleteDC(hMainDC);
} }
String OS_Windows::_quote_command_line_argument(const String &p_text) const {
for (int i = 0; i < p_text.size(); i++) {
CharType c = p_text[i];
if (c == ' ' || c == '&' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '=' || c == ';' || c == '!' || c == '\'' || c == '+' || c == ',' || c == '`' || c == '~') {
return "\"" + p_text + "\"";
}
}
return p_text;
}
Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
if (p_blocking && r_pipe) { if (p_blocking && r_pipe) {
String argss = _quote_command_line_argument(p_path);
String argss;
argss = "\"\"" + p_path + "\"";
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
argss += " " + _quote_command_line_argument(E->get());
argss += " \"" + E->get() + "\"";
} }
argss += "\"";
if (read_stderr) { if (read_stderr) {
argss += " 2>&1"; // Read stderr too argss += " 2>&1"; // Read stderr too
} }
// Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command.
argss = _quote_command_line_argument(argss);
FILE *f = _wpopen(argss.c_str(), L"r"); FILE *f = _wpopen(argss.c_str(), L"r");
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
char buf[65535]; char buf[65535];
@ -2805,20 +2810,19 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
} }
int rv = _pclose(f); int rv = _pclose(f);
if (r_exitcode) if (r_exitcode) {
*r_exitcode = rv; *r_exitcode = rv;
}
return OK; return OK;
} }
String cmdline = "\"" + p_path + "\""; String cmdline = _quote_command_line_argument(p_path);
const List<String>::Element *I = p_arguments.front(); const List<String>::Element *I = p_arguments.front();
while (I) { while (I) {
cmdline += " " + _quote_command_line_argument(I->get());
cmdline += " \"" + I->get() + "\"";
I = I->next(); I = I->next();
}; }
ProcessInfo pi; ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si)); ZeroMemory(&pi.si, sizeof(pi.si));
@ -2826,18 +2830,21 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi)); ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
Vector<CharType> modstr; //windows wants to change this no idea why Vector<CharType> modstr; // Windows wants to change this no idea why.
modstr.resize(cmdline.size()); modstr.resize(cmdline.size());
for (int i = 0; i < cmdline.size(); i++) for (int i = 0; i < cmdline.size(); i++) {
modstr.write[i] = cmdline[i]; modstr.write[i] = cmdline[i];
}
int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, NULL, NULL, si_w, &pi.pi); int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, NULL, NULL, si_w, &pi.pi);
ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
if (p_blocking) { if (p_blocking) {
DWORD ret2 = WaitForSingleObject(pi.pi.hProcess, INFINITE); DWORD ret2 = WaitForSingleObject(pi.pi.hProcess, INFINITE);
if (r_exitcode) if (r_exitcode) {
*r_exitcode = ret2; *r_exitcode = ret2;
}
CloseHandle(pi.pi.hProcess); CloseHandle(pi.pi.hProcess);
CloseHandle(pi.pi.hThread); CloseHandle(pi.pi.hThread);
@ -2846,9 +2853,9 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ProcessID pid = pi.pi.dwProcessId; ProcessID pid = pi.pi.dwProcessId;
if (r_child_id) { if (r_child_id) {
*r_child_id = pid; *r_child_id = pid;
}; }
process_map->insert(pid, pi); process_map->insert(pid, pi);
}; }
return OK; return OK;
}; };

View File

@ -377,6 +377,8 @@ protected:
void process_events(); void process_events();
void process_key_events(); void process_key_events();
String _quote_command_line_argument(const String &p_text) const;
struct ProcessInfo { struct ProcessInfo {
STARTUPINFO si; STARTUPINFO si;