Commit 6bdce49d authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[base] Use std::wstring for NativeEnvironmentString on Windows

This change modifies base::NativeEnvironmentString to be std::wstring on
Windows and updates affected code.

Bug: 911896
Change-Id: Ib39c473f42a2cd3384dd6fefd11021e4636629c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1891311Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712523}
parent 492c93d5
...@@ -49,14 +49,12 @@ class BASE_EXPORT Environment { ...@@ -49,14 +49,12 @@ class BASE_EXPORT Environment {
}; };
#if defined(OS_WIN) #if defined(OS_WIN)
using NativeEnvironmentString = string16; using NativeEnvironmentString = std::wstring;
using EnvironmentMap =
std::map<NativeEnvironmentString, NativeEnvironmentString>;
#elif defined(OS_POSIX) || defined(OS_FUCHSIA) #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
using NativeEnvironmentString = std::string; using NativeEnvironmentString = std::string;
#endif
using EnvironmentMap = using EnvironmentMap =
std::map<NativeEnvironmentString, NativeEnvironmentString>; std::map<NativeEnvironmentString, NativeEnvironmentString>;
#endif
} // namespace base } // namespace base
......
...@@ -87,14 +87,14 @@ std::unique_ptr<char* []> AlterEnvironment(const char* const* const env, ...@@ -87,14 +87,14 @@ std::unique_ptr<char* []> AlterEnvironment(const char* const* const env,
#elif defined(OS_WIN) #elif defined(OS_WIN)
NativeEnvironmentString AlterEnvironment(const char16* env, NativeEnvironmentString AlterEnvironment(const wchar_t* env,
const EnvironmentMap& changes) { const EnvironmentMap& changes) {
NativeEnvironmentString result; NativeEnvironmentString result;
// First build up all of the unchanged environment strings. // First build up all of the unchanged environment strings.
const char16* ptr = env; const wchar_t* ptr = env;
while (*ptr) { while (*ptr) {
string16 key; std::wstring key;
size_t line_length = ParseEnvLine(ptr, &key); size_t line_length = ParseEnvLine(ptr, &key);
// Keep only values not specified in the change vector. // Keep only values not specified in the change vector.
...@@ -107,8 +107,8 @@ NativeEnvironmentString AlterEnvironment(const char16* env, ...@@ -107,8 +107,8 @@ NativeEnvironmentString AlterEnvironment(const char16* env,
// Now append all modified and new values. // Now append all modified and new values.
for (const auto& i : changes) { for (const auto& i : changes) {
// Windows environment blocks cannot handle keys or values with NULs. // Windows environment blocks cannot handle keys or values with NULs.
CHECK_EQ(string16::npos, i.first.find(STRING16_LITERAL('\0'))); CHECK_EQ(std::wstring::npos, i.first.find(L'\0'));
CHECK_EQ(string16::npos, i.second.find(STRING16_LITERAL('\0'))); CHECK_EQ(std::wstring::npos, i.second.find(L'\0'));
if (!i.second.empty()) { if (!i.second.empty()) {
result += i.first; result += i.first;
result.push_back('='); result.push_back('=');
......
...@@ -43,7 +43,7 @@ BASE_EXPORT std::unique_ptr<char*[]> AlterEnvironment( ...@@ -43,7 +43,7 @@ BASE_EXPORT std::unique_ptr<char*[]> AlterEnvironment(
// extra terminating null character. So, e.g., the environment A=1 B=2 is // extra terminating null character. So, e.g., the environment A=1 B=2 is
// represented as L"A=1\0B=2\0\0". // represented as L"A=1\0B=2\0\0".
BASE_EXPORT NativeEnvironmentString BASE_EXPORT NativeEnvironmentString
AlterEnvironment(const char16* env, const EnvironmentMap& changes); AlterEnvironment(const wchar_t* env, const EnvironmentMap& changes);
#endif // OS_* #endif // OS_*
} // namespace internal } // namespace internal
......
...@@ -19,9 +19,9 @@ namespace internal { ...@@ -19,9 +19,9 @@ namespace internal {
#if defined(OS_WIN) #if defined(OS_WIN)
namespace { namespace {
void ExpectEnvironmentBlock(const std::vector<string16>& vars, void ExpectEnvironmentBlock(const std::vector<std::wstring>& vars,
const string16& block) { const std::wstring& block) {
string16 expected; std::wstring expected;
for (const auto& var : vars) { for (const auto& var : vars) {
expected += var; expected += var;
expected.push_back('\0'); expected.push_back('\0');
...@@ -32,62 +32,60 @@ void ExpectEnvironmentBlock(const std::vector<string16>& vars, ...@@ -32,62 +32,60 @@ void ExpectEnvironmentBlock(const std::vector<string16>& vars,
} // namespace } // namespace
TEST_F(EnvironmentInternalTest, AlterEnvironment) { TEST_F(EnvironmentInternalTest, AlterEnvironment) {
const char16 empty[] = {'\0'}; const wchar_t empty[] = {'\0'};
const char16 a2[] = {'A', '=', '2', '\0', '\0'}; const wchar_t a2[] = {'A', '=', '2', '\0', '\0'};
const char16 a2b3[] = {'A', '=', '2', '\0', 'B', '=', '3', '\0', '\0'}; const wchar_t a2b3[] = {'A', '=', '2', '\0', 'B', '=', '3', '\0', '\0'};
EnvironmentMap changes; EnvironmentMap changes;
NativeEnvironmentString e; NativeEnvironmentString e;
e = AlterEnvironment(empty, changes); e = AlterEnvironment(empty, changes);
ExpectEnvironmentBlock({}, e); ExpectEnvironmentBlock({}, e);
changes[STRING16_LITERAL("A")] = STRING16_LITERAL("1"); changes[L"A"] = L"1";
e = AlterEnvironment(empty, changes); e = AlterEnvironment(empty, changes);
ExpectEnvironmentBlock({STRING16_LITERAL("A=1")}, e); ExpectEnvironmentBlock({L"A=1"}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = string16(); changes[L"A"] = std::wstring();
e = AlterEnvironment(empty, changes); e = AlterEnvironment(empty, changes);
ExpectEnvironmentBlock({}, e); ExpectEnvironmentBlock({}, e);
changes.clear(); changes.clear();
e = AlterEnvironment(a2, changes); e = AlterEnvironment(a2, changes);
ExpectEnvironmentBlock({STRING16_LITERAL("A=2")}, e); ExpectEnvironmentBlock({L"A=2"}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = STRING16_LITERAL("1"); changes[L"A"] = L"1";
e = AlterEnvironment(a2, changes); e = AlterEnvironment(a2, changes);
ExpectEnvironmentBlock({STRING16_LITERAL("A=1")}, e); ExpectEnvironmentBlock({L"A=1"}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = string16(); changes[L"A"] = std::wstring();
e = AlterEnvironment(a2, changes); e = AlterEnvironment(a2, changes);
ExpectEnvironmentBlock({}, e); ExpectEnvironmentBlock({}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = string16(); changes[L"A"] = std::wstring();
changes[STRING16_LITERAL("B")] = string16(); changes[L"B"] = std::wstring();
e = AlterEnvironment(a2b3, changes); e = AlterEnvironment(a2b3, changes);
ExpectEnvironmentBlock({}, e); ExpectEnvironmentBlock({}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = string16(); changes[L"A"] = std::wstring();
e = AlterEnvironment(a2b3, changes); e = AlterEnvironment(a2b3, changes);
ExpectEnvironmentBlock({STRING16_LITERAL("B=3")}, e); ExpectEnvironmentBlock({L"B=3"}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("B")] = string16(); changes[L"B"] = std::wstring();
e = AlterEnvironment(a2b3, changes); e = AlterEnvironment(a2b3, changes);
ExpectEnvironmentBlock({STRING16_LITERAL("A=2")}, e); ExpectEnvironmentBlock({L"A=2"}, e);
changes.clear(); changes.clear();
changes[STRING16_LITERAL("A")] = STRING16_LITERAL("1"); changes[L"A"] = L"1";
changes[STRING16_LITERAL("C")] = STRING16_LITERAL("4"); changes[L"C"] = L"4";
e = AlterEnvironment(a2b3, changes); e = AlterEnvironment(a2b3, changes);
// AlterEnvironment() currently always puts changed entries at the end. // AlterEnvironment() currently always puts changed entries at the end.
ExpectEnvironmentBlock({STRING16_LITERAL("B=3"), STRING16_LITERAL("A=1"), ExpectEnvironmentBlock({L"B=3", L"A=1", L"C=4"}, e);
STRING16_LITERAL("C=4")},
e);
} }
#else // !OS_WIN #else // !OS_WIN
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/command_line.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/process/process.h" #include "base/process/process.h"
...@@ -38,8 +39,6 @@ ...@@ -38,8 +39,6 @@
namespace base { namespace base {
class CommandLine;
#if defined(OS_WIN) #if defined(OS_WIN)
typedef std::vector<HANDLE> HandlesToInheritVector; typedef std::vector<HANDLE> HandlesToInheritVector;
#elif defined(OS_FUCHSIA) #elif defined(OS_FUCHSIA)
...@@ -321,7 +320,7 @@ BASE_EXPORT Process LaunchProcess(const CommandLine& cmdline, ...@@ -321,7 +320,7 @@ BASE_EXPORT Process LaunchProcess(const CommandLine& cmdline,
// //
// Example (including literal quotes) // Example (including literal quotes)
// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
BASE_EXPORT Process LaunchProcess(const string16& cmdline, BASE_EXPORT Process LaunchProcess(const CommandLine::StringType& cmdline,
const LaunchOptions& options); const LaunchOptions& options);
// Launches a process with elevated privileges. This does not behave exactly // Launches a process with elevated privileges. This does not behave exactly
...@@ -379,7 +378,8 @@ BASE_EXPORT bool GetAppOutputWithExitCode(const CommandLine& cl, ...@@ -379,7 +378,8 @@ BASE_EXPORT bool GetAppOutputWithExitCode(const CommandLine& cl,
// A Windows-specific version of GetAppOutput that takes a command line string // A Windows-specific version of GetAppOutput that takes a command line string
// instead of a CommandLine object. Useful for situations where you need to // instead of a CommandLine object. Useful for situations where you need to
// control the command line arguments directly. // control the command line arguments directly.
BASE_EXPORT bool GetAppOutput(const StringPiece16& cl, std::string* output); BASE_EXPORT bool GetAppOutput(CommandLine::StringPieceType cl,
std::string* output);
#elif defined(OS_POSIX) || defined(OS_FUCHSIA) #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
// A POSIX-specific version of GetAppOutput that takes an argv array // A POSIX-specific version of GetAppOutput that takes an argv array
// instead of a CommandLine. Useful for situations where you need to // instead of a CommandLine. Useful for situations where you need to
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/debug/activity_tracker.h" #include "base/debug/activity_tracker.h"
#include "base/debug/stack_trace.h" #include "base/debug/stack_trace.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -36,7 +35,7 @@ namespace base { ...@@ -36,7 +35,7 @@ namespace base {
namespace { namespace {
bool GetAppOutputInternal(const StringPiece16& cl, bool GetAppOutputInternal(CommandLine::StringPieceType cl,
bool include_stderr, bool include_stderr,
std::string* output, std::string* output,
int* exit_code) { int* exit_code) {
...@@ -82,8 +81,8 @@ bool GetAppOutputInternal(const StringPiece16& cl, ...@@ -82,8 +81,8 @@ bool GetAppOutputInternal(const StringPiece16& cl,
// Create the child process. // Create the child process.
PROCESS_INFORMATION temp_process_info = {}; PROCESS_INFORMATION temp_process_info = {};
if (!CreateProcess(nullptr, as_writable_wcstr(writable_command_line_string), if (!CreateProcess(nullptr, data(writable_command_line_string), nullptr,
nullptr, nullptr, nullptr,
TRUE, // Handles are inherited. TRUE, // Handles are inherited.
0, nullptr, nullptr, &start_info, &temp_process_info)) { 0, nullptr, nullptr, &start_info, &temp_process_info)) {
NOTREACHED() << "Failed to start process"; NOTREACHED() << "Failed to start process";
...@@ -199,7 +198,7 @@ Process LaunchProcess(const CommandLine& cmdline, ...@@ -199,7 +198,7 @@ Process LaunchProcess(const CommandLine& cmdline,
return LaunchProcess(cmdline.GetCommandLineString(), options); return LaunchProcess(cmdline.GetCommandLineString(), options);
} }
Process LaunchProcess(const string16& cmdline, Process LaunchProcess(const CommandLine::StringType& cmdline,
const LaunchOptions& options) { const LaunchOptions& options) {
// Mitigate the issues caused by loading DLLs on a background thread // Mitigate the issues caused by loading DLLs on a background thread
// (http://crbug/973868). // (http://crbug/973868).
...@@ -278,9 +277,9 @@ Process LaunchProcess(const string16& cmdline, ...@@ -278,9 +277,9 @@ Process LaunchProcess(const string16& cmdline,
LPCTSTR current_directory = options.current_directory.empty() LPCTSTR current_directory = options.current_directory.empty()
? nullptr ? nullptr
: as_wcstr(options.current_directory.value()); : options.current_directory.value().c_str();
string16 writable_cmdline(cmdline); auto writable_cmdline(cmdline);
DCHECK(!(flags & CREATE_SUSPENDED)) DCHECK(!(flags & CREATE_SUSPENDED))
<< "Creating a suspended process can lead to hung processes if the " << "Creating a suspended process can lead to hung processes if the "
<< "launching process is killed before it assigns the process to the" << "launching process is killed before it assigns the process to the"
...@@ -299,21 +298,21 @@ Process LaunchProcess(const string16& cmdline, ...@@ -299,21 +298,21 @@ Process LaunchProcess(const string16& cmdline,
DCHECK(options.environment.empty()); DCHECK(options.environment.empty());
BOOL launched = CreateProcessAsUser( BOOL launched = CreateProcessAsUser(
options.as_user, nullptr, as_writable_wcstr(writable_cmdline), nullptr, options.as_user, nullptr, data(writable_cmdline), nullptr, nullptr,
nullptr, inherit_handles, flags, environment_block, current_directory, inherit_handles, flags, environment_block, current_directory,
startup_info, &temp_process_info); startup_info, &temp_process_info);
DestroyEnvironmentBlock(environment_block); DestroyEnvironmentBlock(environment_block);
if (!launched) { if (!launched) {
DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline) DPLOG(ERROR) << "Command line:" << std::endl
<< std::endl; << WideToUTF8(cmdline) << std::endl;
return Process(); return Process();
} }
} else { } else {
char16* new_environment = nullptr; wchar_t* new_environment = nullptr;
string16 env_storage; std::wstring env_storage;
if (options.clear_environment || !options.environment.empty()) { if (options.clear_environment || !options.environment.empty()) {
if (options.clear_environment) { if (options.clear_environment) {
static const char16 kEmptyEnvironment[] = {0}; static const wchar_t kEmptyEnvironment[] = {0};
env_storage = env_storage =
internal::AlterEnvironment(kEmptyEnvironment, options.environment); internal::AlterEnvironment(kEmptyEnvironment, options.environment);
} else { } else {
...@@ -322,20 +321,18 @@ Process LaunchProcess(const string16& cmdline, ...@@ -322,20 +321,18 @@ Process LaunchProcess(const string16& cmdline,
DPLOG(ERROR); DPLOG(ERROR);
return Process(); return Process();
} }
env_storage = internal::AlterEnvironment(as_u16cstr(old_environment), env_storage =
options.environment); internal::AlterEnvironment(old_environment, options.environment);
FreeEnvironmentStrings(old_environment); FreeEnvironmentStrings(old_environment);
} }
new_environment = data(env_storage); new_environment = data(env_storage);
flags |= CREATE_UNICODE_ENVIRONMENT; flags |= CREATE_UNICODE_ENVIRONMENT;
} }
if (!CreateProcess(nullptr, as_writable_wcstr(writable_cmdline), nullptr, if (!CreateProcess(nullptr, data(writable_cmdline), nullptr, nullptr,
nullptr, inherit_handles, flags, inherit_handles, flags, new_environment,
as_writable_wcstr(new_environment), current_directory, current_directory, startup_info, &temp_process_info)) {
startup_info, &temp_process_info)) { DPLOG(ERROR) << "Command line:" << std::endl << cmdline << std::endl;
DPLOG(ERROR) << "Command line:" << std::endl
<< UTF16ToUTF8(cmdline) << std::endl;
return Process(); return Process();
} }
} }
...@@ -365,16 +362,16 @@ Process LaunchProcess(const string16& cmdline, ...@@ -365,16 +362,16 @@ Process LaunchProcess(const string16& cmdline,
Process LaunchElevatedProcess(const CommandLine& cmdline, Process LaunchElevatedProcess(const CommandLine& cmdline,
const LaunchOptions& options) { const LaunchOptions& options) {
const string16 file = cmdline.GetProgram().value(); const FilePath::StringType file = cmdline.GetProgram().value();
const string16 arguments = cmdline.GetArgumentsString(); const CommandLine::StringType arguments = cmdline.GetArgumentsString();
SHELLEXECUTEINFO shex_info = {}; SHELLEXECUTEINFO shex_info = {};
shex_info.cbSize = sizeof(shex_info); shex_info.cbSize = sizeof(shex_info);
shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; shex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
shex_info.hwnd = GetActiveWindow(); shex_info.hwnd = GetActiveWindow();
shex_info.lpVerb = L"runas"; shex_info.lpVerb = L"runas";
shex_info.lpFile = as_wcstr(file); shex_info.lpFile = file.c_str();
shex_info.lpParameters = as_wcstr(arguments); shex_info.lpParameters = arguments.c_str();
shex_info.lpDirectory = nullptr; shex_info.lpDirectory = nullptr;
shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOWNORMAL; shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOWNORMAL;
shex_info.hInstApp = nullptr; shex_info.hInstApp = nullptr;
...@@ -419,7 +416,7 @@ bool GetAppOutputWithExitCode(const CommandLine& cl, ...@@ -419,7 +416,7 @@ bool GetAppOutputWithExitCode(const CommandLine& cl,
cl.GetCommandLineString(), false, output, exit_code); cl.GetCommandLineString(), false, output, exit_code);
} }
bool GetAppOutput(const StringPiece16& cl, std::string* output) { bool GetAppOutput(CommandLine::StringPieceType cl, std::string* output) {
int exit_code; int exit_code;
return GetAppOutputInternal(cl, false, output, &exit_code); return GetAppOutputInternal(cl, false, output, &exit_code);
} }
......
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