From 83bebf4519e626a89378c26a3ab6b00bb401f274 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 2 Jun 2026 12:31:52 +1000 Subject: [PATCH] [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 --- idd/LGIdd/CSettings.cpp | 50 +++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/idd/LGIdd/CSettings.cpp b/idd/LGIdd/CSettings.cpp index 58743d85..6f806341 100644 --- a/idd/LGIdd/CSettings.cpp +++ b/idd/LGIdd/CSettings.cpp @@ -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 buf(cb / sizeof(wchar_t) + 1); - ec = RegQueryValueExW(hKey, name, nullptr, &type, - reinterpret_cast(buf.data()), &cb); + std::vector buf((cb / sizeof(wchar_t)) + 1, L'\0'); + + DWORD type2 = 0; + DWORD cb2 = cb; + + ec = RegQueryValueExW( + hKey, + name, + nullptr, + &type2, + reinterpret_cast(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; }