Fix SHGetPathFromIDListLongPath (#16545)

The function did not truncate the string afterwards, so you ended up with a very long string containing null terminators on the end. This wouldn't have caused an issue when passing it as a char *, but due to it now being passed as string or string_view, this causes issues.

It also wouldn't have worked for paths greater than MAX_PATH, because it wasn't passing the buffer size to the function.
This commit is contained in:
Ted John 2022-01-31 21:35:48 +00:00 committed by GitHub
parent 6d0bb48b68
commit f84c2851be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 6 deletions

View File

@ -41,17 +41,26 @@
static std::wstring SHGetPathFromIDListLongPath(LPCITEMIDLIST pidl)
{
# if defined(__MINGW32__)
std::wstring pszPath(MAX_PATH, 0);
while (!SHGetPathFromIDListW(pidl, &pszPath[0]))
auto result = SHGetPathFromIDListW(pidl, pszPath.data());
# else
// Limit path length to 32K
std::wstring pszPath(std::numeric_limits<int16_t>().max(), 0);
auto result = SHGetPathFromIDListEx(pidl, pszPath.data(), static_cast<DWORD>(pszPath.size()), GPFIDL_DEFAULT);
# endif
if (result)
{
if (pszPath.size() >= SHRT_MAX)
// Truncate at first null terminator
auto length = pszPath.find(L'\0');
if (length != std::wstring::npos)
{
// Clearly not succeeding at all, bail
return std::wstring();
pszPath.resize(length);
pszPath.shrink_to_fit();
}
pszPath.resize(pszPath.size() * 2);
return pszPath;
}
return pszPath;
return std::wstring();
}
namespace OpenRCT2::Ui