shill: OpenVPNDriver: Quote options containing spaces
When converting from command line arguments to config files,
the previous OpenVPN CL neglected to deal with arguments
containing spaces. These need to be quoted.
BUG=chromium:269600
TEST=Unit tests
Change-Id: Id6aa5e8ed5eb9a97580d6ffe3bbb30992be5293a
Reviewed-on: https://gerrit.chromium.org/gerrit/64981
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
diff --git a/openvpn_driver.cc b/openvpn_driver.cc
index 60f67ee..c2af243 100644
--- a/openvpn_driver.cc
+++ b/openvpn_driver.cc
@@ -228,7 +228,23 @@
char separator) {
vector<string> option_strings;
for (const auto &option : options) {
- option_strings.push_back(JoinString(option, ' '));
+ vector<string> quoted_option;
+ for (const auto &argument : option) {
+ if (argument.find(' ') != string::npos ||
+ argument.find('\t') != string::npos ||
+ argument.find('"') != string::npos ||
+ argument.find(separator) != string::npos) {
+ string quoted_argument(argument);
+ const char separator_chars[] = { separator, '\0' };
+ ReplaceChars(argument, separator_chars, " ", "ed_argument);
+ ReplaceChars(quoted_argument, "\\", "\\\\", "ed_argument);
+ ReplaceChars(quoted_argument, "\"", "\\\"", "ed_argument);
+ quoted_option.push_back("\"" + quoted_argument + "\"");
+ } else {
+ quoted_option.push_back(argument);
+ }
+ }
+ option_strings.push_back(JoinString(quoted_option, ' '));
}
return JoinString(option_strings, separator);
}
diff --git a/openvpn_driver_unittest.cc b/openvpn_driver_unittest.cc
index 72bc923..e7a2929 100644
--- a/openvpn_driver_unittest.cc
+++ b/openvpn_driver_unittest.cc
@@ -1237,8 +1237,9 @@
const char kOption1[] = "option1";
const char kOption1Argument0[] = "option1-argument0";
const char kOption2[] = "option2";
- const char kOption2Argument0[] = "option2-argument0";
- const char kOption2Argument1[] = "option2-argument1";
+ const char kOption2Argument0[] = "option2-argument0\n\t\"'\\";
+ const char kOption2Argument0Transformed[] = "option2-argument0 \t\\\"'\\\\";
+ const char kOption2Argument1[] = "option2-argument1 space";
vector<vector<string>> options {
{ kOption0 },
{ kOption1, kOption1Argument0 },
@@ -1256,10 +1257,10 @@
string config_contents;
EXPECT_TRUE(file_util::ReadFileToString(config_file, &config_contents));
string expected_config_contents = StringPrintf(
- "%s\n%s %s\n%s %s %s\n",
+ "%s\n%s %s\n%s \"%s\" \"%s\"\n",
kOption0,
kOption1, kOption1Argument0,
- kOption2, kOption2Argument0, kOption2Argument1);
+ kOption2, kOption2Argument0Transformed, kOption2Argument1);
EXPECT_EQ(expected_config_contents, config_contents);
}