| Index: chrome/install_static/install_util.cc
|
| diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc
|
| index 2a8f83aed0707aadd9d629a91d4dcc206de98117..e382da488f92b6d7425e9adf43014d0f35df8eef 100644
|
| --- a/chrome/install_static/install_util.cc
|
| +++ b/chrome/install_static/install_util.cc
|
| @@ -7,7 +7,10 @@
|
| #include <windows.h>
|
| #include <assert.h>
|
| #include <algorithm>
|
| +#include <iostream>
|
| +#include <iterator>
|
| #include <memory>
|
| +#include <sstream>
|
|
|
| #include "base/macros.h"
|
| #include "build/build_config.h"
|
| @@ -93,7 +96,7 @@ void Trace(const wchar_t* format_string, ...) {
|
| bool ReadKeyValueString(bool system_install, const wchar_t* key_path,
|
| const wchar_t* guid, const wchar_t* value_to_read,
|
| base::string16* value_out) {
|
| - HKEY key = NULL;
|
| + HKEY key = nullptr;
|
| value_out->clear();
|
|
|
| base::string16 full_key_path(key_path);
|
| @@ -144,7 +147,7 @@ bool ReadKeyValueString(bool system_install, const wchar_t* key_path,
|
| bool ReadKeyValueDW(bool system_install, const wchar_t* key_path,
|
| base::string16 guid, const wchar_t* value_to_read,
|
| DWORD* value_out) {
|
| - HKEY key = NULL;
|
| + HKEY key = nullptr;
|
| *value_out = 0;
|
|
|
| base::string16 full_key_path(key_path);
|
| @@ -255,41 +258,6 @@ base::string16 GetCurrentProcessExePath() {
|
| return exe_path;
|
| }
|
|
|
| -// UTF8 to UTF16 and vice versa conversion helpers. We cannot use the base
|
| -// string conversion utilities here as they bring about a dependency on
|
| -// user32.dll which is not allowed in this file.
|
| -
|
| -// Convert a UTF16 string to an UTF8 string.
|
| -std::string utf16_to_utf8(const base::string16 &source) {
|
| - if (source.empty())
|
| - return std::string();
|
| - int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
|
| - static_cast<int>(source.size()), nullptr, 0, nullptr, nullptr);
|
| - std::string result(size, '\0');
|
| - if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
|
| - static_cast<int>(source.size()), &result[0], size, nullptr,
|
| - nullptr) != size) {
|
| - assert(false);
|
| - return std::string();
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -// Convert a UTF8 string to a UTF16 string.
|
| -base::string16 utf8_to_string16(const std::string &source) {
|
| - if (source.empty())
|
| - return base::string16();
|
| - int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
|
| - static_cast<int>(source.size()), nullptr, 0);
|
| - base::string16 result(size, L'\0');
|
| - if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
|
| - static_cast<int>(source.size()), &result[0], size) != size) {
|
| - assert(false);
|
| - return base::string16();
|
| - }
|
| - return result;
|
| -}
|
| -
|
| bool RecursiveDirectoryCreate(const base::string16& full_path) {
|
| // If the path exists, we've succeeded if it's a directory, failed otherwise.
|
| const wchar_t* full_path_str = full_path.c_str();
|
| @@ -318,7 +286,7 @@ bool RecursiveDirectoryCreate(const base::string16& full_path) {
|
| return false;
|
| }
|
| }
|
| - if (!::CreateDirectory(full_path_str, NULL)) {
|
| + if (!::CreateDirectory(full_path_str, nullptr)) {
|
| DWORD error_code = ::GetLastError();
|
| if (error_code == ERROR_ALREADY_EXISTS) {
|
| DWORD file_attributes = ::GetFileAttributes(full_path_str);
|
| @@ -419,10 +387,25 @@ bool MatchPatternImpl(const base::string16& source,
|
| return false;
|
| }
|
|
|
| +// Defines the type of whitespace characters typically found in strings.
|
| +constexpr char kWhiteSpaces[] = " \t\n\r\f\v";
|
| +
|
| +// Trim whitespaces from left & right
|
| +void Trim(std::string* str) {
|
| + str->erase(str->find_last_not_of(kWhiteSpaces) + 1);
|
| + str->erase(0, str->find_first_not_of(kWhiteSpaces));
|
| +}
|
| +
|
| +bool IsValidNumber(const std::string& str) {
|
| + if (str.empty())
|
| + return false;
|
| + return std::all_of(str.begin(), str.end(), ::isdigit);
|
| +}
|
| +
|
| } // namespace
|
|
|
| bool IsSxSChrome(const wchar_t* exe_path) {
|
| - return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL;
|
| + return wcsstr(exe_path, L"Chrome SxS\\Application") != nullptr;
|
| }
|
|
|
| bool IsSystemInstall(const wchar_t* exe_path) {
|
| @@ -463,7 +446,7 @@ bool GetCollectStatsConsentForTesting(const base::string16& exe_path) {
|
| }
|
|
|
| bool ReportingIsEnforcedByPolicy(bool* metrics_is_enforced_by_policy) {
|
| - HKEY key = NULL;
|
| + HKEY key = nullptr;
|
| DWORD value = 0;
|
| BYTE* value_bytes = reinterpret_cast<BYTE*>(&value);
|
| DWORD size = sizeof(value);
|
| @@ -497,7 +480,7 @@ void InitializeProcessType() {
|
| typedef bool (*IsSandboxedProcessFunc)();
|
| IsSandboxedProcessFunc is_sandboxed_process_func =
|
| reinterpret_cast<IsSandboxedProcessFunc>(
|
| - GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess"));
|
| + GetProcAddress(GetModuleHandle(nullptr), "IsSandboxedProcess"));
|
| if (is_sandboxed_process_func && is_sandboxed_process_func()) {
|
| g_process_type = ProcessType::NON_BROWSER_PROCESS;
|
| return;
|
| @@ -575,25 +558,25 @@ bool GetDefaultCrashDumpLocation(base::string16* crash_dir) {
|
|
|
|
|
| std::string GetEnvironmentString(const std::string& variable_name) {
|
| - DWORD value_length = ::GetEnvironmentVariable(
|
| - utf8_to_string16(variable_name).c_str(), NULL, 0);
|
| + DWORD value_length =
|
| + ::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), nullptr, 0);
|
| if (value_length == 0)
|
| return std::string();
|
| std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]);
|
| - ::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
|
| - value.get(), value_length);
|
| - return utf16_to_utf8(value.get());
|
| + ::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), value.get(),
|
| + value_length);
|
| + return UTF16ToUTF8(value.get());
|
| }
|
|
|
| bool SetEnvironmentString(const std::string& variable_name,
|
| const std::string& new_value) {
|
| - return !!SetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
|
| - utf8_to_string16(new_value).c_str());
|
| + return !!SetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(),
|
| + UTF8ToUTF16(new_value).c_str());
|
| }
|
|
|
| bool HasEnvironmentVariable(const std::string& variable_name) {
|
| - return !!::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
|
| - NULL, 0);
|
| + return !!::GetEnvironmentVariable(UTF8ToUTF16(variable_name).c_str(), nullptr,
|
| + 0);
|
| }
|
|
|
| bool GetExecutableVersionDetails(const base::string16& exe_path,
|
| @@ -712,7 +695,7 @@ std::string GetGoogleUpdateVersion() {
|
| nullptr,
|
| kRegGoogleUpdateVersion,
|
| &update_version)) {
|
| - return utf16_to_utf8(update_version);
|
| + return UTF16ToUTF8(update_version);
|
| }
|
| return std::string();
|
| }
|
| @@ -743,4 +726,129 @@ bool MatchPattern(const base::string16& source,
|
| return MatchPatternImpl(source, pattern, 0, 0);
|
| }
|
|
|
| +std::string UTF16ToUTF8(const base::string16& source) {
|
| + if (source.empty() ||
|
| + static_cast<int>(source.size()) > std::numeric_limits<int>::max()) {
|
| + return std::string();
|
| + }
|
| + int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
|
| + static_cast<int>(source.size()), nullptr, 0,
|
| + nullptr, nullptr);
|
| + std::string result(size, '\0');
|
| + if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
|
| + static_cast<int>(source.size()), &result[0], size,
|
| + nullptr, nullptr) != size) {
|
| + assert(false);
|
| + return std::string();
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +base::string16 UTF8ToUTF16(const std::string& source) {
|
| + if (source.empty() ||
|
| + static_cast<int>(source.size()) > std::numeric_limits<int>::max()) {
|
| + return base::string16();
|
| + }
|
| + int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
|
| + static_cast<int>(source.size()), nullptr, 0);
|
| + base::string16 result(size, L'\0');
|
| + if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
|
| + static_cast<int>(source.size()), &result[0],
|
| + size) != size) {
|
| + assert(false);
|
| + return base::string16();
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +std::vector<std::string> TokenizeString(const std::string& str,
|
| + char delimiter,
|
| + bool trim_spaces) {
|
| + std::vector<std::string> tokens;
|
| + std::istringstream buffer(str);
|
| + for (std::string token; std::getline(buffer, token, delimiter);) {
|
| + if (trim_spaces)
|
| + Trim(&token);
|
| + tokens.push_back(token);
|
| + }
|
| + return tokens;
|
| +}
|
| +
|
| +bool CompareVersionStrings(const std::string& version1,
|
| + const std::string& version2,
|
| + int* result) {
|
| + if (version1.empty() || version2.empty())
|
| + return false;
|
| +
|
| + // Tokenize both version strings with "." as the separator. If either of
|
| + // the returned token lists are empty then bail.
|
| + std::vector<std::string> version1_components =
|
| + TokenizeString(version1, '.', false);
|
| + if (version1_components.empty())
|
| + return false;
|
| +
|
| + std::vector<std::string> version2_components =
|
| + TokenizeString(version2, '.', false);
|
| + if (version2_components.empty())
|
| + return false;
|
| +
|
| + // You may have less tokens in either string. Use the minimum of the number
|
| + // of tokens as the initial count.
|
| + const size_t count =
|
| + std::min(version1_components.size(), version2_components.size());
|
| + for (size_t i = 0; i < count; ++i) {
|
| + // If either of the version components don't contain valid numeric digits
|
| + // bail.
|
| + if (!IsValidNumber(version1_components[i]) ||
|
| + !IsValidNumber(version2_components[i])) {
|
| + return false;
|
| + }
|
| +
|
| + int version1_component = std::stoi(version1_components[i]);
|
| + int version2_component = std::stoi(version2_components[i]);
|
| +
|
| + if (version1_component > version2_component) {
|
| + *result = 1;
|
| + return true;
|
| + }
|
| +
|
| + if (version1_component < version2_component) {
|
| + *result = -1;
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + // Handle remaining tokens. Here if we have non zero tokens remaining in the
|
| + // version 1 list then it means that the version1 string is larger. If the
|
| + // version 1 token list has tokens left, then if either of these tokens is
|
| + // greater than 0 then it means that the version1 string is smaller than the
|
| + // version2 string.
|
| + if (version1_components.size() > version2_components.size()) {
|
| + for (size_t i = count; i < version1_components.size(); ++i) {
|
| + // If the version components don't contain valid numeric digits bail.
|
| + if (!IsValidNumber(version1_components[i]))
|
| + return false;
|
| +
|
| + if (std::stoi(version1_components[i]) > 0) {
|
| + *result = 1;
|
| + return true;
|
| + }
|
| + }
|
| + } else if (version1_components.size() < version2_components.size()) {
|
| + for (size_t i = count; i < version2_components.size(); ++i) {
|
| + // If the version components don't contain valid numeric digits bail.
|
| + if (!IsValidNumber(version2_components[i]))
|
| + return false;
|
| +
|
| + if (std::stoi(version2_components[i]) > 0) {
|
| + *result = -1;
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + // Here it means that both versions are equal.
|
| + *result = 0;
|
| + return true;
|
| +}
|
| +
|
| } // namespace install_static
|
|
|