Bug 620931 part 2.5 - Properly quote arguments on Windows when starting child processes. r=rstrong

This commit is contained in:
Mike Hommey
2011-05-12 15:44:35 +02:00
parent b10f57ab45
commit 73acccdaca
3 changed files with 48 additions and 22 deletions

View File

@@ -115,9 +115,7 @@ ReplaceAll(const string& haystack, const string& needle, const string& with)
string string
MungePluginDsoPath(const string& path) MungePluginDsoPath(const string& path)
{ {
#if defined(XP_WIN) #if defined(OS_LINUX)
return "\""+ path +"\"";
#elif defined(OS_LINUX)
// https://bugzilla.mozilla.org/show_bug.cgi?id=519601 // https://bugzilla.mozilla.org/show_bug.cgi?id=519601
return ReplaceAll(path, "netscape", "netsc@pe"); return ReplaceAll(path, "netscape", "netsc@pe");
#else #else

View File

@@ -264,24 +264,55 @@ void CommandLine::AppendSwitch(const std::wstring& switch_string) {
switches_[WideToASCII(switch_string)] = L""; switches_[WideToASCII(switch_string)] = L"";
} }
void CommandLine::AppendSwitchWithValue(const std::wstring& switch_string, // Quote a string if necessary, such that CommandLineToArgvW() will
const std::wstring& value_string) { // always process it as a single argument.
std::wstring value_string_edit; static std::wstring WindowsStyleQuote(const std::wstring& arg) {
// We follow the quoting rules of CommandLineToArgvW.
// NOTE(jhughes): If the value contains a quotation mark at one // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
// end but not both, you may get unusable output. if (arg.find_first_of(L" \\\"\t") == std::wstring::npos) {
if (!value_string.empty() && // No quoting necessary.
(value_string.find(L" ") != std::wstring::npos) && return arg;
(value_string[0] != L'"') &&
(value_string[value_string.length() - 1] != L'"')) {
// need to provide quotes
value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str());
} else {
value_string_edit = value_string;
} }
std::wstring out;
out.push_back(L'"');
for (size_t i = 0; i < arg.size(); ++i) {
if (arg[i] == '\\') {
// Find the extent of this run of backslashes.
size_t start = i, end = start + 1;
for (; end < arg.size() && arg[end] == '\\'; ++end)
/* empty */;
size_t backslash_count = end - start;
// Backslashes are escapes only if the run is followed by a double quote.
// Since we also will end the string with a double quote, we escape for
// either a double quote or the end of the string.
if (end == arg.size() || arg[end] == '"') {
// To quote, we need to output 2x as many backslashes.
backslash_count *= 2;
}
for (size_t j = 0; j < backslash_count; ++j)
out.push_back('\\');
// Advance i to one before the end to balance i++ in loop.
i = end - 1;
} else if (arg[i] == '"') {
out.push_back('\\');
out.push_back('"');
} else {
out.push_back(arg[i]);
}
}
out.push_back('"');
return out;
}
void CommandLine::AppendSwitchWithValue(const std::wstring& switch_string,
const std::wstring& value_string) {
std::wstring quoted_value_string = WindowsStyleQuote(value_string);
std::wstring combined_switch_string = std::wstring combined_switch_string =
PrefixedSwitchStringWithValue(switch_string, value_string_edit); PrefixedSwitchStringWithValue(switch_string, quoted_value_string);
command_line_string_.append(L" "); command_line_string_.append(L" ");
command_line_string_.append(combined_switch_string); command_line_string_.append(combined_switch_string);
@@ -290,9 +321,8 @@ void CommandLine::AppendSwitchWithValue(const std::wstring& switch_string,
} }
void CommandLine::AppendLooseValue(const std::wstring& value) { void CommandLine::AppendLooseValue(const std::wstring& value) {
// TODO(evan): quoting?
command_line_string_.append(L" "); command_line_string_.append(L" ");
command_line_string_.append(value); command_line_string_.append(WindowsStyleQuote(value));
} }
void CommandLine::AppendArguments(const CommandLine& other, void CommandLine::AppendArguments(const CommandLine& other,

View File

@@ -261,9 +261,7 @@ void GeckoChildProcessHost::InitWindowsGroupID()
taskbarInfo->GetAvailable(&isSupported); taskbarInfo->GetAvailable(&isSupported);
nsAutoString appId; nsAutoString appId;
if (isSupported && NS_SUCCEEDED(taskbarInfo->GetDefaultGroupId(appId))) { if (isSupported && NS_SUCCEEDED(taskbarInfo->GetDefaultGroupId(appId))) {
mGroupId.Assign(PRUnichar('\"'));
mGroupId.Append(appId); mGroupId.Append(appId);
mGroupId.Append(PRUnichar('\"'));
} else { } else {
mGroupId.AssignLiteral("-"); mGroupId.AssignLiteral("-");
} }