diff options
| author | Billy O'Neal <bion@microsoft.com> | 2020-05-18 12:48:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-18 12:48:09 -0700 |
| commit | 0e9e59f2c4ff7fec9c11373f9b9bf076317328b2 (patch) | |
| tree | df9307c2774b1cca1e06daaf41c29b1b5525f00a | |
| parent | 87b2ae5500de635cc62b0ad652217d4819e7cffa (diff) | |
| download | vcpkg-0e9e59f2c4ff7fec9c11373f9b9bf076317328b2.tar.gz vcpkg-0e9e59f2c4ff7fec9c11373f9b9bf076317328b2.zip | |
[vcpkg] Hardem expand environment strings path with explicit integer overflow checks and resistance to CP_ACP. (#11315)
| -rw-r--r-- | toolsrc/src/vcpkg/commands.edit.cpp | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 8391b3476..59e5cc6cf 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include <limits.h> #include <vcpkg/base/strings.h> #include <vcpkg/base/system.print.h> #include <vcpkg/base/system.process.h> @@ -7,17 +8,17 @@ #include <vcpkg/help.h> #include <vcpkg/paragraphs.h> -namespace vcpkg::Commands::Edit -{ #if defined(_WIN32) - static std::vector<fs::path> find_from_registry() +namespace +{ + std::vector<fs::path> find_from_registry() { std::vector<fs::path> output; struct RegKey { HKEY root; - StringLiteral subkey; + vcpkg::StringLiteral subkey; } REGKEYS[] = { {HKEY_LOCAL_MACHINE, R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)"}, @@ -33,8 +34,8 @@ namespace vcpkg::Commands::Edit for (auto&& keypath : REGKEYS) { - const Optional<std::string> code_installpath = - System::get_registry_string(keypath.root, keypath.subkey, "InstallLocation"); + const vcpkg::Optional<std::string> code_installpath = + vcpkg::System::get_registry_string(keypath.root, keypath.subkey, "InstallLocation"); if (const auto c = code_installpath.get()) { const fs::path install_path = fs::u8path(*c); @@ -44,8 +45,39 @@ namespace vcpkg::Commands::Edit } return output; } + + std::string expand_environment_strings(const std::string& input) + { + const auto widened = vcpkg::Strings::to_utf16(input); + std::wstring result; + result.resize(result.capacity()); + bool done; + do + { + if (result.size() == ULONG_MAX) + { + vcpkg::Checks::exit_fail(VCPKG_LINE_INFO); // integer overflow + } + + const auto required_size = + ExpandEnvironmentStringsW(widened.c_str(), &result[0], static_cast<unsigned long>(result.size() + 1)); + if (required_size == 0) + { + vcpkg::System::print2(vcpkg::System::Color::error, "Error: could not expand the environment string:\n"); + vcpkg::System::print2(vcpkg::System::Color::error, input); + vcpkg::Checks::exit_fail(VCPKG_LINE_INFO); + } + + done = required_size <= result.size() + 1; + result.resize(required_size - 1); + } while (!done); + return vcpkg::Strings::to_utf8(result); + } +} #endif +namespace vcpkg::Commands::Edit +{ static constexpr StringLiteral OPTION_BUILDTREES = "--buildtrees"; static constexpr StringLiteral OPTION_ALL = "--all"; @@ -171,17 +203,12 @@ namespace vcpkg::Commands::Edit const auto txt_default = System::get_registry_string(HKEY_CLASSES_ROOT, R"(.txt\ShellNew)", "ItemName"); if (const auto entry = txt_default.get()) { -#ifdef UNICODE - LPWSTR dst = new wchar_t[MAX_PATH]; - ExpandEnvironmentStrings(Strings::to_utf16(*entry).c_str(), dst, MAX_PATH); - auto full_path = Strings::to_utf8(dst); -#else - LPSTR dst = new char[MAX_PATH]; - ExpandEnvironmentStrings(entry->c_str(), dst, MAX_PATH); - auto full_path = std::string(dst); -#endif - auto begin = full_path.find_first_not_of('@'); - candidate_paths.push_back(fs::u8path(full_path.substr(begin, full_path.find_first_of(',') - begin))); + auto full_path = expand_environment_strings(*entry); + auto first = full_path.begin(); + const auto last = full_path.end(); + first = std::find_if_not(first, last, [](const char c) { return c == '@'; }); + const auto comma = std::find(first, last, ','); + candidate_paths.push_back(fs::u8path(first, comma)); } #elif defined(__APPLE__) candidate_paths.push_back( |
