Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1202)

Side by Side Diff: base/command_line.cc

Issue 595803002: base::CommandLine: Added optional quoting of placeholder arguments. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase off CL 602253006. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/command_line.h ('k') | base/command_line_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 #if defined(OS_WIN) 98 #if defined(OS_WIN)
99 return base::StringToLowerASCII(string); 99 return base::StringToLowerASCII(string);
100 #elif defined(OS_POSIX) 100 #elif defined(OS_POSIX)
101 return string; 101 return string;
102 #endif 102 #endif
103 } 103 }
104 104
105 105
106 #if defined(OS_WIN) 106 #if defined(OS_WIN)
107 // Quote a string as necessary for CommandLineToArgvW compatiblity *on Windows*. 107 // Quote a string as necessary for CommandLineToArgvW compatiblity *on Windows*.
108 base::string16 QuoteForCommandLineToArgvW(const base::string16& arg) { 108 base::string16 QuoteForCommandLineToArgvW(const base::string16& arg,
109 bool quote_placeholders) {
109 // We follow the quoting rules of CommandLineToArgvW. 110 // We follow the quoting rules of CommandLineToArgvW.
110 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx 111 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
111 if (arg.find_first_of(L" \\\"") == base::string16::npos) { 112 base::string16 quotable_chars(L" \\\"");
113 // We may also be required to quote '%', which is commonly used in a command
114 // line as a placeholder. (It may be substituted for a string with spaces.)
115 if (quote_placeholders)
116 quotable_chars.push_back(L'%');
117 if (arg.find_first_of(quotable_chars) == base::string16::npos) {
112 // No quoting necessary. 118 // No quoting necessary.
113 return arg; 119 return arg;
114 } 120 }
115 121
116 base::string16 out; 122 base::string16 out;
117 out.push_back(L'"'); 123 out.push_back(L'"');
118 for (size_t i = 0; i < arg.size(); ++i) { 124 for (size_t i = 0; i < arg.size(); ++i) {
119 if (arg[i] == '\\') { 125 if (arg[i] == '\\') {
120 // Find the extent of this run of backslashes. 126 // Find the extent of this run of backslashes.
121 size_t start = i, end = start + 1; 127 size_t start = i, end = start + 1;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 246 }
241 247
242 void CommandLine::InitFromArgv(const StringVector& argv) { 248 void CommandLine::InitFromArgv(const StringVector& argv) {
243 argv_ = StringVector(1); 249 argv_ = StringVector(1);
244 switches_.clear(); 250 switches_.clear();
245 begin_args_ = 1; 251 begin_args_ = 1;
246 SetProgram(argv.empty() ? FilePath() : FilePath(argv[0])); 252 SetProgram(argv.empty() ? FilePath() : FilePath(argv[0]));
247 AppendSwitchesAndArguments(*this, argv); 253 AppendSwitchesAndArguments(*this, argv);
248 } 254 }
249 255
250 CommandLine::StringType CommandLine::GetCommandLineString() const {
251 StringType string(argv_[0]);
252 #if defined(OS_WIN)
253 string = QuoteForCommandLineToArgvW(string);
254 #endif
255 StringType params(GetArgumentsString());
256 if (!params.empty()) {
257 string.append(StringType(FILE_PATH_LITERAL(" ")));
258 string.append(params);
259 }
260 return string;
261 }
262
263 CommandLine::StringType CommandLine::GetArgumentsString() const {
264 StringType params;
265 // Append switches and arguments.
266 bool parse_switches = true;
267 for (size_t i = 1; i < argv_.size(); ++i) {
268 StringType arg = argv_[i];
269 StringType switch_string;
270 StringType switch_value;
271 parse_switches &= arg != kSwitchTerminator;
272 if (i > 1)
273 params.append(StringType(FILE_PATH_LITERAL(" ")));
274 if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) {
275 params.append(switch_string);
276 if (!switch_value.empty()) {
277 #if defined(OS_WIN)
278 switch_value = QuoteForCommandLineToArgvW(switch_value);
279 #endif
280 params.append(kSwitchValueSeparator + switch_value);
281 }
282 }
283 else {
284 #if defined(OS_WIN)
285 arg = QuoteForCommandLineToArgvW(arg);
286 #endif
287 params.append(arg);
288 }
289 }
290 return params;
291 }
292
293 FilePath CommandLine::GetProgram() const { 256 FilePath CommandLine::GetProgram() const {
294 return FilePath(argv_[0]); 257 return FilePath(argv_[0]);
295 } 258 }
296 259
297 void CommandLine::SetProgram(const FilePath& program) { 260 void CommandLine::SetProgram(const FilePath& program) {
298 TrimWhitespace(program.value(), TRIM_ALL, &argv_[0]); 261 TrimWhitespace(program.value(), TRIM_ALL, &argv_[0]);
299 } 262 }
300 263
301 bool CommandLine::HasSwitch(const std::string& switch_string) const { 264 bool CommandLine::HasSwitch(const std::string& switch_string) const {
302 return switches_.find(LowerASCIIOnWindows(switch_string)) != switches_.end(); 265 return switches_.find(LowerASCIIOnWindows(switch_string)) != switches_.end();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 wchar_t** args = NULL; 395 wchar_t** args = NULL;
433 args = ::CommandLineToArgvW(command_line_string.c_str(), &num_args); 396 args = ::CommandLineToArgvW(command_line_string.c_str(), &num_args);
434 397
435 DPLOG_IF(FATAL, !args) << "CommandLineToArgvW failed on command line: " 398 DPLOG_IF(FATAL, !args) << "CommandLineToArgvW failed on command line: "
436 << UTF16ToUTF8(command_line); 399 << UTF16ToUTF8(command_line);
437 InitFromArgv(num_args, args); 400 InitFromArgv(num_args, args);
438 LocalFree(args); 401 LocalFree(args);
439 } 402 }
440 #endif 403 #endif
441 404
405 CommandLine::StringType CommandLine::GetCommandLineStringInternal(
406 bool quote_placeholders) const {
407 StringType string(argv_[0]);
408 #if defined(OS_WIN)
409 string = QuoteForCommandLineToArgvW(string, quote_placeholders);
410 #endif
411 StringType params(GetArgumentsStringInternal(quote_placeholders));
412 if (!params.empty()) {
413 string.append(StringType(FILE_PATH_LITERAL(" ")));
414 string.append(params);
415 }
416 return string;
417 }
418
419 CommandLine::StringType CommandLine::GetArgumentsStringInternal(
420 bool quote_placeholders) const {
421 StringType params;
422 // Append switches and arguments.
423 bool parse_switches = true;
424 for (size_t i = 1; i < argv_.size(); ++i) {
425 StringType arg = argv_[i];
426 StringType switch_string;
427 StringType switch_value;
428 parse_switches &= arg != kSwitchTerminator;
429 if (i > 1)
430 params.append(StringType(FILE_PATH_LITERAL(" ")));
431 if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) {
432 params.append(switch_string);
433 if (!switch_value.empty()) {
434 #if defined(OS_WIN)
435 switch_value =
436 QuoteForCommandLineToArgvW(switch_value, quote_placeholders);
437 #endif
438 params.append(kSwitchValueSeparator + switch_value);
439 }
440 }
441 else {
442 #if defined(OS_WIN)
443 arg = QuoteForCommandLineToArgvW(arg, quote_placeholders);
444 #endif
445 params.append(arg);
446 }
447 }
448 return params;
449 }
450
442 } // namespace base 451 } // namespace base
OLDNEW
« no previous file with comments | « base/command_line.h ('k') | base/command_line_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698