diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index eca5be4e498..b7c3aff4094 100755 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2770,26 +2770,31 @@ void OS_Windows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, 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 &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) { - - String argss; - argss = "\"\"" + p_path + "\""; - + String argss = _quote_command_line_argument(p_path); for (const List::Element *E = p_arguments.front(); E; E = E->next()) { - - argss += " \"" + E->get() + "\""; + argss += " " + _quote_command_line_argument(E->get()); } - argss += "\""; - if (read_stderr) { 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"); - ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); char buf[65535]; @@ -2805,20 +2810,19 @@ Error OS_Windows::execute(const String &p_path, const List &p_arguments, } int rv = _pclose(f); - if (r_exitcode) + if (r_exitcode) { *r_exitcode = rv; + } return OK; } - String cmdline = "\"" + p_path + "\""; + String cmdline = _quote_command_line_argument(p_path); const List::Element *I = p_arguments.front(); while (I) { - - cmdline += " \"" + I->get() + "\""; - + cmdline += " " + _quote_command_line_argument(I->get()); I = I->next(); - }; + } ProcessInfo pi; ZeroMemory(&pi.si, sizeof(pi.si)); @@ -2826,18 +2830,21 @@ Error OS_Windows::execute(const String &p_path, const List &p_arguments, ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - Vector modstr; //windows wants to change this no idea why + Vector modstr; // Windows wants to change this no idea why. 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]; + } + 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); if (p_blocking) { DWORD ret2 = WaitForSingleObject(pi.pi.hProcess, INFINITE); - if (r_exitcode) + if (r_exitcode) { *r_exitcode = ret2; + } CloseHandle(pi.pi.hProcess); CloseHandle(pi.pi.hThread); @@ -2846,9 +2853,9 @@ Error OS_Windows::execute(const String &p_path, const List &p_arguments, ProcessID pid = pi.pi.dwProcessId; if (r_child_id) { *r_child_id = pid; - }; + } process_map->insert(pid, pi); - }; + } return OK; }; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 98fe78f15f3..5ee50c66f92 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -377,6 +377,8 @@ protected: void process_events(); void process_key_events(); + String _quote_command_line_argument(const String &p_text) const; + struct ProcessInfo { STARTUPINFO si;