Commit 74ae85ac authored by Jesse McKenna's avatar Jesse McKenna Committed by Commit Bot

Replace --single-argument= with --single-argument

This change changes the command-line single-argument switch, used for
launches from the Windows shell, from `--single-argument=` to
`--single-argument `. This fixes an issue where users who have updated
but not restarted Chrome are unable to open shell links (due to the
mismatch between the just-updated open command in the registry and the
expectations of the now-obsolete running browser).

crrev.com/c/21165961 changed the command line used by the Windows shell
(and set in the registry) from `"chrome.exe" "%1"` (where %1 is
replaced by the argument to launch by the shell) to
`"chrome.exe" --single-argument=%1` to enforce a limit of one
argument on shell-based launches.

This caused old versions (those which have updated but not restarted
Chrome) to receive `--single-argument=<arg>` when Chrome is invoked
from the shell, but be unable to interpret it. Because this change
replaces the `=` with ` `, it is more backwards-compatible with old
versions. They will simply ignore the `--single-argument` switch and
interpret the space-delimited <arg> as the argument until the user
restarts Chrome to launch the new version.

Bug: 1092913
Change-Id: Iba734fe290944176f7ad38d36e670a1bea04623b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2238270Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Commit-Queue: Jesse McKenna <jessemckenna@google.com>
Cr-Commit-Position: refs/heads/master@{#778584}
parent f930eea8
...@@ -549,12 +549,16 @@ CommandLine::StringType CommandLine::GetCommandLineString() const { ...@@ -549,12 +549,16 @@ CommandLine::StringType CommandLine::GetCommandLineString() const {
} }
#if defined(OS_WIN) #if defined(OS_WIN)
// NOTE: this function is used to set Chrome's open command in the registry
// during update. Any change to the syntax must be compatible with the prior
// version, to prevent shell-launch functionality from breaking in between the
// update and the browser restarting (see crbug.com/1092913).
CommandLine::StringType CommandLine::GetCommandLineStringForShell() const { CommandLine::StringType CommandLine::GetCommandLineStringForShell() const {
DCHECK(GetArgs().empty()); DCHECK(GetArgs().empty());
StringType command_line_string = GetCommandLineString(); StringType command_line_string = GetCommandLineString();
return command_line_string + FILE_PATH_LITERAL(" ") + return command_line_string + FILE_PATH_LITERAL(" ") +
kSwitchPrefixes[0].as_string() + kSingleArgument + kSwitchPrefixes[0].as_string() + kSingleArgument +
kSwitchValueSeparator + FILE_PATH_LITERAL("%1"); FILE_PATH_LITERAL(" %1");
} }
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
...@@ -589,25 +593,26 @@ CommandLine::StringType CommandLine::GetArgumentsString() const { ...@@ -589,25 +593,26 @@ CommandLine::StringType CommandLine::GetArgumentsString() const {
#if defined(OS_WIN) #if defined(OS_WIN)
void CommandLine::ParseAsSingleArgument( void CommandLine::ParseAsSingleArgument(
const CommandLine::StringType& single_arg_switch_string) { const CommandLine::StringType& single_arg_switch) {
DCHECK(!raw_command_line_string_.empty()); DCHECK(!raw_command_line_string_.empty());
// Remove any previously parsed arguments. // Remove any previously parsed arguments.
argv_.resize(begin_args_); argv_.resize(begin_args_);
// Locate "--single-argument=" in the process's raw command line. Results are // Locate "--single-argument" in the process's raw command line. Results are
// unpredictable if "--single-argument=" appears as part of a previous // unpredictable if "--single-argument" appears as part of a previous
// argument or switch. // argument or switch.
StringType single_arg_switch =
single_arg_switch_string + kSwitchValueSeparator;
const size_t single_arg_switch_position = const size_t single_arg_switch_position =
raw_command_line_string_.find(single_arg_switch); raw_command_line_string_.find(single_arg_switch);
CHECK_NE(single_arg_switch_position, StringType::npos); CHECK_NE(single_arg_switch_position, StringType::npos);
// Append the portion of the raw command line that comes after // Append the portion of the raw command line that starts one character past
// "--single-argument=" as the one and only argument. // "--single-argument" as the one and only argument, or return if no
// argument is present.
const size_t arg_position = const size_t arg_position =
single_arg_switch_position + single_arg_switch.length(); single_arg_switch_position + single_arg_switch.length() + 1;
if (arg_position >= raw_command_line_string_.length())
return;
const StringPieceType arg = raw_command_line_string_.substr(arg_position); const StringPieceType arg = raw_command_line_string_.substr(arg_position);
if (!arg.empty()) { if (!arg.empty()) {
AppendArgNative(arg.as_string()); AppendArgNative(arg.as_string());
......
...@@ -119,7 +119,7 @@ class BASE_EXPORT CommandLine { ...@@ -119,7 +119,7 @@ class BASE_EXPORT CommandLine {
#if defined(OS_WIN) #if defined(OS_WIN)
// Returns the command-line string in the proper format for the Windows shell, // Returns the command-line string in the proper format for the Windows shell,
// ending with the argument placeholder "--single-argument=%1". The single- // ending with the argument placeholder "--single-argument %1". The single-
// argument switch prevents unexpected parsing of arguments from other // argument switch prevents unexpected parsing of arguments from other
// software that cannot be trusted to escape double quotes when substituting // software that cannot be trusted to escape double quotes when substituting
// into a placeholder (e.g., "%1" placeholders populated by the Windows // into a placeholder (e.g., "%1" placeholders populated by the Windows
...@@ -218,9 +218,11 @@ class BASE_EXPORT CommandLine { ...@@ -218,9 +218,11 @@ class BASE_EXPORT CommandLine {
#if defined(OS_WIN) #if defined(OS_WIN)
// Initializes by parsing |raw_command_line_string_|, treating everything // Initializes by parsing |raw_command_line_string_|, treating everything
// after |single_arg_switch_string| + "=" as the command line's single // after |single_arg_switch_string| + <a single character> as the command
// argument, and dropping any arguments previously parsed. The command line // line's single argument, and dropping any arguments previously parsed. The
// must contain |single_arg_switch_string| followed by "=". // command line must contain |single_arg_switch_string|, and the argument, if
// present, must be separated from |single_arg_switch_string| by one
// character.
// NOTE: the single-argument switch is not preserved after parsing; // NOTE: the single-argument switch is not preserved after parsing;
// GetCommandLineStringForShell() must be used to reproduce the original // GetCommandLineStringForShell() must be used to reproduce the original
// command-line string with single-argument switch. // command-line string with single-argument switch.
......
...@@ -318,7 +318,7 @@ TEST(CommandLineTest, GetCommandLineStringForShell) { ...@@ -318,7 +318,7 @@ TEST(CommandLineTest, GetCommandLineStringForShell) {
FILE_PATH_LITERAL("program --switch /switch2 --")); FILE_PATH_LITERAL("program --switch /switch2 --"));
EXPECT_EQ( EXPECT_EQ(
cl.GetCommandLineStringForShell(), cl.GetCommandLineStringForShell(),
FILE_PATH_LITERAL("program --switch /switch2 -- --single-argument=%1")); FILE_PATH_LITERAL("program --switch /switch2 -- --single-argument %1"));
} }
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
...@@ -568,13 +568,21 @@ TEST(CommandLineTest, MultipleSameSwitch) { ...@@ -568,13 +568,21 @@ TEST(CommandLineTest, MultipleSameSwitch) {
TEST(CommandLineTest, ParseAsSingleArgument) { TEST(CommandLineTest, ParseAsSingleArgument) {
CommandLine cl = CommandLine::FromString( CommandLine cl = CommandLine::FromString(
FILE_PATH_LITERAL("program --switch_before arg_before " FILE_PATH_LITERAL("program --switch_before arg_before "
"--single-argument=arg with spaces \"and quotes\" \"")); "--single-argument arg with spaces \"and quotes\" \""));
EXPECT_FALSE(cl.GetCommandLineString().empty()); EXPECT_FALSE(cl.GetCommandLineString().empty());
EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")), cl.GetProgram()); EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")), cl.GetProgram());
EXPECT_TRUE(cl.HasSwitch("switch_before")); EXPECT_TRUE(cl.HasSwitch("switch_before"));
EXPECT_EQ(cl.GetArgs(), CommandLine::StringVector({FILE_PATH_LITERAL( EXPECT_EQ(cl.GetArgs(), CommandLine::StringVector({FILE_PATH_LITERAL(
"arg with spaces \"and quotes\" \"")})); "arg with spaces \"and quotes\" \"")}));
CommandLine cl_without_arg =
CommandLine::FromString(FILE_PATH_LITERAL("program --single-argument "));
EXPECT_FALSE(cl_without_arg.GetCommandLineString().empty());
EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")),
cl_without_arg.GetProgram());
EXPECT_TRUE(cl_without_arg.GetArgs().empty());
} }
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
......
...@@ -861,7 +861,7 @@ TEST_F(ShellUtilRegistryTest, AddFileAssociations) { ...@@ -861,7 +861,7 @@ TEST_F(ShellUtilRegistryTest, AddFileAssociations) {
key.Open(HKEY_CURRENT_USER, key.Open(HKEY_CURRENT_USER,
L"Software\\Classes\\TestApp\\shell\\open\\command", KEY_READ)); L"Software\\Classes\\TestApp\\shell\\open\\command", KEY_READ));
EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(L"", &value)); EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(L"", &value));
EXPECT_EQ(L"\"C:\\test.exe\" --single-argument=%1", value); EXPECT_EQ(L"\"C:\\test.exe\" --single-argument %1", value);
// The Application subkey and values are only required by Windows 8 and later. // The Application subkey and values are only required by Windows 8 and later.
if (base::win::GetVersion() >= base::win::Version::WIN8) { if (base::win::GetVersion() >= base::win::Version::WIN8) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment