mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
util/register: fix crashing when value string contains non-ascii chars
We can't use RegGetValueA because RegGetValueA converts wide string to non UTF-8 string, which results in crashing when printing
This commit is contained in:
@@ -11,18 +11,18 @@ void ffDetectBios(FFBiosResult* bios)
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error))
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, "BIOSVersion", &bios->biosRelease, &bios->error))
|
||||
if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->biosRelease, &bios->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, "BIOSVendor", &bios->biosVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, "BIOSReleaseDate", &bios->biosDate, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->biosVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->biosDate, NULL);
|
||||
|
||||
uint32_t major, minor;
|
||||
if(
|
||||
ffRegReadUint(hKey, "BiosMajorRelease", &major, NULL) &&
|
||||
ffRegReadUint(hKey, "BiosMinorRelease", &minor, NULL)
|
||||
ffRegReadUint(hKey, L"BiosMajorRelease", &major, NULL) &&
|
||||
ffRegReadUint(hKey, L"BiosMinorRelease", &minor, NULL)
|
||||
)
|
||||
ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor);
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ void ffDetectBoard(FFBoardResult* board)
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error))
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, "BaseBoardProduct", &board->boardName, &board->error))
|
||||
if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->boardName, &board->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, "BaseBoardManufacturer", &board->boardVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, "BaseBoardVersion", &board->boardVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->boardVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->boardVersion, NULL);
|
||||
}
|
||||
|
||||
@@ -39,15 +39,15 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
cpu->coresLogical = (uint16_t)GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
|
||||
return;
|
||||
|
||||
{
|
||||
uint32_t mhz;
|
||||
if(ffRegReadUint(hKey, "~MHz", &mhz, NULL))
|
||||
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
|
||||
cpu->frequencyMax = mhz / 1000.0;
|
||||
}
|
||||
|
||||
ffRegReadStrbuf(hKey, "ProcessorNameString", &cpu->name, NULL);
|
||||
ffRegReadStrbuf(hKey, "VendorIdentifier", &cpu->vendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL);
|
||||
ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
FF_UNUSED(instance);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "Control Panel\\Cursors", &hKey, &result->error))
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error))
|
||||
ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error))
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error))
|
||||
return;
|
||||
|
||||
ffRegReadStrbuf(hKey, "SystemProductName", &host->productName, NULL);
|
||||
ffRegReadStrbuf(hKey, "SystemFamily", &host->productFamily, NULL);
|
||||
ffRegReadStrbuf(hKey, "SystemVersion", &host->productVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, "SystemSKU", &host->productSku, NULL);
|
||||
ffRegReadStrbuf(hKey, "SystemManufacturer", &host->sysVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemProductName", &host->productName, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemFamily", &host->productFamily, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemVersion", &host->productVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemSKU", &host->productSku, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemManufacturer", &host->sysVendor, NULL);
|
||||
}
|
||||
|
||||
@@ -31,16 +31,16 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term
|
||||
//Current font of conhost doesn't seem to be detectable, we detect default font instead
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, "Console", &hKey, &terminalFont->error))
|
||||
if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Console", &hKey, &terminalFont->error))
|
||||
return;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
if(!ffRegReadStrbuf(hKey, "FaceName", &fontName, &terminalFont->error))
|
||||
if(!ffRegReadStrbuf(hKey, L"FaceName", &fontName, &terminalFont->error))
|
||||
return;
|
||||
|
||||
uint32_t fontSizeNum = 0;
|
||||
if(!ffRegReadUint(hKey, "FontSize", &fontSizeNum, &terminalFont->error))
|
||||
if(!ffRegReadUint(hKey, L"FontSize", &fontSizeNum, &terminalFont->error))
|
||||
return;
|
||||
|
||||
char fontSize[16];
|
||||
|
||||
@@ -7,23 +7,23 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError)
|
||||
FF_UNUSED(instance);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL))
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL))
|
||||
{
|
||||
uint32_t SystemUsesLightTheme = 1;
|
||||
if(!ffRegReadUint(hKey, "SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError))
|
||||
if(!ffRegReadUint(hKey, L"SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError))
|
||||
return false;
|
||||
|
||||
uint32_t AppsUsesLightTheme = 1;
|
||||
if(!ffRegReadUint(hKey, "AppsUseLightTheme", &AppsUsesLightTheme, themeOrError))
|
||||
if(!ffRegReadUint(hKey, L"AppsUseLightTheme", &AppsUsesLightTheme, themeOrError))
|
||||
return false;
|
||||
|
||||
ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark");
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL))
|
||||
else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL))
|
||||
{
|
||||
if(!ffRegReadStrbuf(hKey, "CurrentTheme", themeOrError, themeOrError))
|
||||
if(!ffRegReadStrbuf(hKey, L"CurrentTheme", themeOrError, themeOrError))
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrBeforeLastC(themeOrError, '.');
|
||||
|
||||
+36
-13
@@ -1,4 +1,6 @@
|
||||
#include "register.h"
|
||||
#include "unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
static const char* hKey2Str(HKEY hKey)
|
||||
{
|
||||
@@ -18,41 +20,62 @@ static const char* hKey2Str(HKEY hKey)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const char* lpSubKey, HKEY* result, FFstrbuf* error)
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error)
|
||||
{
|
||||
if(RegOpenKeyExA(hKey, lpSubKey, 0, KEY_READ, result) != ERROR_SUCCESS)
|
||||
if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error)
|
||||
ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), lpSubKey);
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufFromWchar(subKeyW);
|
||||
ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbuf* error)
|
||||
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error)
|
||||
{
|
||||
DWORD bufSize; //with tailing '\0'
|
||||
if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS)
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error) ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)");
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ffStrbufEnsureFree(result, bufSize - 1);
|
||||
if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, result->chars, &bufSize) != ERROR_SUCCESS)
|
||||
wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize);
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)");
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
result->length = bufSize - 1;
|
||||
ffWcharToUtf8(resultW, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error)
|
||||
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error)
|
||||
{
|
||||
DWORD bufSize = sizeof(*result);
|
||||
if(RegGetValueA(hKey, NULL, valueName, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueName ? valueName : "(default)");
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -16,8 +16,8 @@ static inline void wrapRegCloseKey(HKEY* phKey)
|
||||
|
||||
#define FF_HKEY_AUTO_DESTROY HKEY __attribute__((__cleanup__(wrapRegCloseKey)))
|
||||
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const char* lpSubKey, HKEY* result, FFstrbuf* error);
|
||||
bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbuf* error);
|
||||
bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error);
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error);
|
||||
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error);
|
||||
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,3 +15,22 @@ void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result)
|
||||
result->length = (uint32_t)size_needed;
|
||||
result->chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
FFstrbuf ffStrbufFromWchar(const wchar_t* input)
|
||||
{
|
||||
FFstrbuf result;
|
||||
|
||||
int len = input ? (int)wcslen(input) : 0;
|
||||
if(len <= 0)
|
||||
ffStrbufInit(&result);
|
||||
else
|
||||
{
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, input, len, NULL, 0, NULL, NULL);
|
||||
ffStrbufInitA(&result, (uint32_t)size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, input, len, result.chars, size_needed, NULL, NULL);
|
||||
result.length = (uint32_t)size_needed;
|
||||
result.chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result);
|
||||
FFstrbuf ffStrbufFromWchar(const wchar_t* input);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user