[idd] CSettings: fix registry string value handling

Rename the invalid default parameter and make registry string reads
more robust.

Validate the returned value type and byte count after querying the
value data, reject malformed UTF-16 sizes, and explicitly terminate
the string based on the number of bytes actually returned.

Sanity check the parsed mode values
This commit is contained in:
Geoffrey McRae
2026-06-02 12:31:52 +10:00
committed by Geoffrey McRae
parent 19f75dc045
commit 83bebf4519

View File

@@ -103,8 +103,11 @@ void CSettings::SetExtraMode(const DisplayMode& mode)
RegCloseKey(hKey);
}
std::wstring CSettings::ReadStringValue(const wchar_t* name, const wchar_t* default)
std::wstring CSettings::ReadStringValue(const wchar_t* name, const wchar_t* defaultValue)
{
if (!defaultValue)
defaultValue = L"";
HKEY hKey = nullptr;
LONG ec = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
@@ -115,29 +118,43 @@ std::wstring CSettings::ReadStringValue(const wchar_t* name, const wchar_t* defa
);
if (ec != ERROR_SUCCESS)
return std::wstring(default);
return std::wstring(defaultValue);
DWORD type = 0;
DWORD cb = 0;
ec = RegQueryValueExW(hKey, name, nullptr, &type, nullptr, &cb);
if (ec != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ) || cb == 0)
if (ec != ERROR_SUCCESS ||
(type != REG_SZ && type != REG_EXPAND_SZ) ||
cb == 0 ||
(cb % sizeof(wchar_t)) != 0)
{
RegCloseKey(hKey);
return std::wstring(default);
return std::wstring(defaultValue);
}
std::vector<wchar_t> buf(cb / sizeof(wchar_t) + 1);
ec = RegQueryValueExW(hKey, name, nullptr, &type,
reinterpret_cast<LPBYTE>(buf.data()), &cb);
std::vector<wchar_t> buf((cb / sizeof(wchar_t)) + 1, L'\0');
DWORD type2 = 0;
DWORD cb2 = cb;
ec = RegQueryValueExW(
hKey,
name,
nullptr,
&type2,
reinterpret_cast<LPBYTE>(buf.data()),
&cb2
);
RegCloseKey(hKey);
if (ec != ERROR_SUCCESS)
return std::wstring(default);
buf.back() = L'\0';
if (ec != ERROR_SUCCESS || (type2 != REG_SZ && type2 != REG_EXPAND_SZ) ||
cb2 == 0 || (cb2 % sizeof(wchar_t)) != 0 || cb2 > cb)
return std::wstring(defaultValue);
std::wstring s(buf.data());
return s;
buf[cb2 / sizeof(wchar_t)] = L'\0';
return std::wstring(buf.data());
}
bool CSettings::GetExtraMode(DisplayMode& mode)
@@ -226,5 +243,14 @@ bool CSettings::ParseModeString(const std::wstring& in, DisplayMode& out)
!toUnsigned(s.substr(atPos + 1), out.refresh))
return false;
// sanity check
if (out.width < 640 ||
out.height < 480 ||
out.width > 16384 ||
out.height > 16384 ||
out.refresh < 30 ||
out.refresh > 1000)
return false;
return true;
}