[Windows] Add quotes only to the command line arguments with special characters.
This commit is contained in:
parent
9b3d43cb97
commit
cac399a829
|
@ -415,23 +415,30 @@ uint64_t OS_Windows::get_ticks_usec() const {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
String OS_Windows::_quote_command_line_argument(const String &p_text) const {
|
||||||
if (p_blocking && r_pipe) {
|
for (int i = 0; i < p_text.size(); i++) {
|
||||||
String argss;
|
CharType c = p_text[i];
|
||||||
argss = "\"\"" + p_path + "\"";
|
if (c == ' ' || c == '&' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '=' || c == ';' || c == '!' || c == '\'' || c == '+' || c == ',' || c == '`' || c == '~') {
|
||||||
|
return "\"" + p_text + "\"";
|
||||||
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
|
}
|
||||||
argss += " \"" + E->get() + "\"";
|
}
|
||||||
|
return p_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
argss += "\"";
|
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) {
|
||||||
|
String argss = _quote_command_line_argument(p_path);
|
||||||
|
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
|
||||||
|
argss += " " + _quote_command_line_argument(E->get());
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -446,19 +453,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 += " \"" + I->get() + "\"";
|
cmdline += " " + _quote_command_line_argument(I->get());
|
||||||
|
|
||||||
I = I->next();
|
I = I->next();
|
||||||
};
|
}
|
||||||
|
|
||||||
ProcessInfo pi;
|
ProcessInfo pi;
|
||||||
ZeroMemory(&pi.si, sizeof(pi.si));
|
ZeroMemory(&pi.si, sizeof(pi.si));
|
||||||
|
@ -466,17 +473,20 @@ 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(nullptr, modstr.ptrw(), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
|
int ret = CreateProcessW(nullptr, modstr.ptrw(), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, 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);
|
||||||
|
@ -484,9 +494,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,8 @@ protected:
|
||||||
virtual void finalize_core();
|
virtual void finalize_core();
|
||||||
virtual String get_stdin_string(bool p_block);
|
virtual String get_stdin_string(bool p_block);
|
||||||
|
|
||||||
|
String _quote_command_line_argument(const String &p_text) const;
|
||||||
|
|
||||||
struct ProcessInfo {
|
struct ProcessInfo {
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
|
|
Loading…
Reference in New Issue