@@ -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
409432int 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
414451int 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)
15171567std::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