Skip to content

Commit 57978aa

Browse files
authored
SharedUtil.Misc.hpp: Various issues
1 parent d3bf6f7 commit 57978aa

File tree

1 file changed

+83
-28
lines changed

1 file changed

+83
-28
lines changed

Shared/sdk/SharedUtil.Misc.hpp

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,21 @@ SString SharedUtil::GetParentProcessPathFilename(int pid)
9797
if (hProcess)
9898
{
9999
WCHAR szModuleName[MAX_PATH * 2] = {0};
100-
GetModuleFileNameExW(hProcess, nullptr, szModuleName, NUMELMS(szModuleName));
100+
DWORD dwSize = GetModuleFileNameExW(hProcess, nullptr, szModuleName, NUMELMS(szModuleName) - 1);
101101
CloseHandle(hProcess);
102-
SString strModuleName = ToUTF8(szModuleName);
103-
if (FileExists(strModuleName))
102+
103+
if (dwSize > 0)
104104
{
105-
CloseHandle(hSnapshot);
106-
if (IsShortPathName(strModuleName))
107-
return GetSystemLongPathName(strModuleName);
108-
return strModuleName;
105+
// Ensure null termination
106+
szModuleName[std::min(dwSize, (DWORD)(NUMELMS(szModuleName) - 1))] = L'\0';
107+
SString strModuleName = ToUTF8(szModuleName);
108+
if (FileExists(strModuleName))
109+
{
110+
CloseHandle(hSnapshot);
111+
if (IsShortPathName(strModuleName))
112+
return GetSystemLongPathName(strModuleName);
113+
return strModuleName;
114+
}
109115
}
110116
}
111117
}
@@ -200,10 +206,13 @@ static SString ReadRegistryStringValue(HKEY hkRoot, const char* szSubKey, const
200206
DWORD dwBufferSize;
201207
if (RegQueryValueExW(hkTemp, wstrValue, NULL, NULL, NULL, &dwBufferSize) == ERROR_SUCCESS)
202208
{
209+
203210
CScopeAlloc<wchar_t> szBuffer(dwBufferSize + sizeof(wchar_t));
204211
if (RegQueryValueExW(hkTemp, wstrValue, NULL, NULL, (LPBYTE)(wchar_t*)szBuffer, &dwBufferSize) == ERROR_SUCCESS)
205212
{
206-
szBuffer[dwBufferSize / sizeof(wchar_t)] = 0;
213+
// Ensure null termination - dwBufferSize is in bytes, convert to wchar_t units
214+
size_t wcharCount = dwBufferSize / sizeof(wchar_t);
215+
szBuffer[wcharCount] = 0;
207216
strOutResult = ToUTF8((wchar_t*)szBuffer);
208217
bResult = true;
209218
}
@@ -365,7 +374,21 @@ SString SharedUtil::GetPostUpdateConnect()
365374
CArgMap argMap;
366375
argMap.SetFromString(strPostUpdateConnect);
367376
SString strHost = argMap.Get("host");
368-
time_t timeThen = (time_t)std::atoll(argMap.Get("time"));
377+
SString strTimeString = argMap.Get("time");
378+
379+
time_t timeThen = 0;
380+
if (!strTimeString.empty())
381+
{
382+
char* endptr;
383+
long long result = strtoll(strTimeString.c_str(), &endptr, 10);
384+
385+
// Check for valid conversion
386+
if (endptr != strTimeString.c_str() && *endptr == '\0' &&
387+
result >= 0 && result <= LLONG_MAX)
388+
{
389+
timeThen = static_cast<time_t>(result);
390+
}
391+
}
369392

370393
// Expire after 5 mins
371394
double seconds = difftime(time(NULL), timeThen);
@@ -408,7 +431,21 @@ void SharedUtil::SetApplicationSettingInt(const SString& strPath, const SString&
408431

409432
int SharedUtil::GetApplicationSettingInt(const SString& strPath, const SString& strName)
410433
{
411-
return atoi(GetApplicationSetting(strPath, strName));
434+
SString strValue = GetApplicationSetting(strPath, strName);
435+
if (strValue.empty())
436+
return 0;
437+
438+
char* endptr;
439+
long result = strtol(strValue.c_str(), &endptr, 10);
440+
441+
// Check for conversion errors
442+
if (endptr == strValue.c_str() || *endptr != '\0')
443+
return 0; // Invalid conversion
444+
445+
if (result > INT_MAX || result < INT_MIN)
446+
return 0;
447+
448+
return static_cast<int>(result);
412449
}
413450

414451
int SharedUtil::IncApplicationSettingInt(const SString& strPath, const SString& strName)
@@ -618,11 +655,15 @@ SString SharedUtil::GetClipboardText()
618655
{
619656
// Get the clipboard's data
620657
HANDLE clipboardData = GetClipboardData(CF_UNICODETEXT);
621-
void* lockedData = GlobalLock(clipboardData);
622-
if (lockedData)
623-
data = UTF16ToMbUTF8(static_cast<wchar_t*>(lockedData));
624-
625-
GlobalUnlock(clipboardData);
658+
if (clipboardData) // Check if handle is valid
659+
{
660+
void* lockedData = GlobalLock(clipboardData);
661+
if (lockedData)
662+
{
663+
data = UTF16ToMbUTF8(static_cast<wchar_t*>(lockedData));
664+
GlobalUnlock(clipboardData);
665+
}
666+
}
626667
CloseClipboard();
627668
}
628669

@@ -679,7 +720,8 @@ bool SharedUtil::ProcessPendingBrowseToSolution()
679720

680721
ClearPendingBrowseToSolution();
681722

682-
SString strTitle("MTA: San Andreas %s (CTRL+C to copy)", *strErrorCode);
723+
SString strTitle;
724+
strTitle.Format("MTA: San Andreas %s (CTRL+C to copy)", strErrorCode.c_str());
683725
// Show message if set, ask question if required, and then launch URL
684726
if (iFlags & ASK_GO_ONLINE)
685727
{
@@ -769,8 +811,11 @@ void SharedUtil::AddReportLog(uint uiId, const SString& strText, uint uiAmountLi
769811
SString strPathFilename = PathJoin(GetMTADataPath(), "report.log");
770812
MakeSureDirExists(strPathFilename);
771813

772-
SString strMessage("%u: %s %s [%s] - %s\n", uiId, GetTimeString(true, false).c_str(), GetReportLogHeaderText().c_str(),
773-
GetReportLogProcessTag().c_str(), strText.c_str());
814+
SString strMessage;
815+
strMessage.Format("%u: %s %s [%s] - ", uiId, GetTimeString(true, false).c_str(), GetReportLogHeaderText().c_str(),
816+
GetReportLogProcessTag().c_str());
817+
strMessage += strText;
818+
strMessage += "\n";
774819
FileAppend(strPathFilename, &strMessage.at(0), strMessage.length());
775820
OutputDebugLine(SStringX("[ReportLog] ") + strMessage);
776821
}
@@ -785,13 +830,18 @@ void SharedUtil::AddExceptionReportLog(uint uiId, const char* szExceptionName, c
785830
constexpr size_t BOILERPLATE_SIZE = 46;
786831
constexpr size_t MAX_EXCEPTION_NAME_SIZE = 64;
787832
constexpr size_t MAX_EXCEPTION_TEXT_SIZE = 256;
788-
static char szOutput[BOILERPLATE_SIZE + MAX_EXCEPTION_NAME_SIZE + MAX_EXCEPTION_TEXT_SIZE] = {0};
833+
constexpr size_t TOTAL_BUFFER_SIZE = BOILERPLATE_SIZE + MAX_EXCEPTION_NAME_SIZE + MAX_EXCEPTION_TEXT_SIZE;
834+
static char szOutput[TOTAL_BUFFER_SIZE] = {0};
789835

790836
SYSTEMTIME s = {0};
791837
GetSystemTime(&s);
792838

793-
sprintf_s(szOutput, "%u: %04hu-%02hu-%02hu %02hu:%02hu:%02hu - Caught %.*s exception: %.*s\n", uiId, s.wYear, s.wMonth, s.wDay, s.wHour, s.wMinute,
794-
s.wSecond, MAX_EXCEPTION_NAME_SIZE, szExceptionName, MAX_EXCEPTION_TEXT_SIZE, szExceptionText);
839+
// Use _snprintf_s to prevent buffer overflow and ensure null termination
840+
int result = _snprintf_s(szOutput, TOTAL_BUFFER_SIZE, _TRUNCATE,
841+
"%u: %04hu-%02hu-%02hu %02hu:%02hu:%02hu - Caught %.*s exception: %.*s\n",
842+
uiId, s.wYear, s.wMonth, s.wDay, s.wHour, s.wMinute, s.wSecond,
843+
(int)MAX_EXCEPTION_NAME_SIZE, szExceptionName ? szExceptionName : "Unknown",
844+
(int)MAX_EXCEPTION_TEXT_SIZE, szExceptionText ? szExceptionText : "");
795845

796846
OutputDebugString("[ReportLog] ");
797847
OutputDebugString(&szOutput[0]);
@@ -936,7 +986,7 @@ SString SharedUtil::GetSystemErrorMessage(uint uiError, bool bRemoveNewlines, bo
936986
strResult = strResult.Replace("\n", "").Replace("\r", "");
937987

938988
if (bPrependCode)
939-
strResult = SString("Error %u: %s", uiError, *strResult);
989+
strResult.Format("Error %u: %s", uiError, strResult.c_str());
940990

941991
return strResult;
942992
}
@@ -1516,15 +1566,20 @@ int SharedUtil::GetUTF8Confidence(const unsigned char* input, int len)
15161566
// Translate a true ANSI string to the UTF-16 equivalent (reencode+convert)
15171567
std::wstring SharedUtil::ANSIToUTF16(const SString& input)
15181568
{
1569+
if (input.empty())
1570+
return L"";
1571+
15191572
size_t len = mbstowcs(NULL, input.c_str(), input.length());
15201573
if (len == (size_t)-1)
15211574
return L"?";
1522-
wchar_t* wcsOutput = new wchar_t[len + 1];
1523-
mbstowcs(wcsOutput, input.c_str(), input.length());
1524-
wcsOutput[len] = 0; // Null terminate the string
1525-
std::wstring strOutput(wcsOutput);
1526-
delete[] wcsOutput;
1527-
return strOutput;
1575+
1576+
std::vector<wchar_t> wcsOutput(len + 1); // Use vector for automatic cleanup
1577+
size_t result = mbstowcs(wcsOutput.data(), input.c_str(), len);
1578+
if (result == (size_t)-1 || result != len)
1579+
return L"?";
1580+
1581+
wcsOutput[len] = 0; // Null terminate the string
1582+
return std::wstring(wcsOutput.data());
15281583
}
15291584

15301585
// Check for BOM bytes

0 commit comments

Comments
 (0)