diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index 790cdd1e..845b1aa9 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -284,7 +284,7 @@ namespace Components if (pszIn > pszTokenStart) { auto iTokenLen = pszIn - pszTokenStart; - strncpy_s(szTokenBuf, pszTokenStart, _TRUNCATE); + Game::I_strncpyz_s(szTokenBuf, sizeof(szTokenBuf), pszTokenStart, pszIn - pszTokenStart); if (bLocOn) { if (!Game::SEH_GetLocalizedTokenReference(szTokenBuf, szTokenBuf, pszMessageType, errType)) @@ -292,7 +292,7 @@ namespace Components return nullptr; } - iTokenLen = &szTokenBuf[std::strlen(szTokenBuf) + 1] - &szTokenBuf[1]; + iTokenLen = std::strlen(szTokenBuf); } if (iTokenLen + iLen >= szStringSize) @@ -319,7 +319,7 @@ namespace Components if (iInsertLevel <= 0 || iLen <= 0) { - strncpy_s(&pszString[iLen], szStringSize - iLen, szTokenBuf, _TRUNCATE); + Game::I_strcpy(&pszString[iLen], szStringSize - iLen, szTokenBuf); } else { @@ -334,7 +334,7 @@ namespace Components } if (digit == insertIndex) { - strncpy_s(szInsertBuf, &pszString[i + 3], szStringSize - (i + 3)); + Game::I_strcpy(szInsertBuf, sizeof(szInsertBuf), &pszString[i + 3]); pszString[i] = 0; ++insertIndex; break; @@ -342,12 +342,8 @@ namespace Components } } - strncpy_s(&pszString[i], szStringSize - i, szTokenBuf, _TRUNCATE); - - if ((iTokenLen + i) < szStringSize) - { - strncpy_s(&pszString[iTokenLen + i], szStringSize - (iTokenLen + i), szInsertBuf, _TRUNCATE); - } + Game::I_strcpy(&pszString[i], szStringSize - i, szTokenBuf); + Game::I_strcpy(&pszString[iTokenLen + i], szStringSize - (iTokenLen + i), szInsertBuf); iLen -= 3; --iInsertLevel; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index c0df8b60..5c6bf69b 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -805,6 +805,44 @@ namespace Game } } + void I_strncpyz_s(char* dest, std::size_t destsize, const char* src, std::size_t count) + { + if (!destsize && !dest) + { + return; + } + if (!src || !count) + { + *dest = '\0'; + } + else + { + const auto* p = reinterpret_cast(src - 1); + auto* q = reinterpret_cast(dest - 1); + auto n = count + 1; + auto s = count; + if (destsize <= count) + { + n = destsize + 1; + s = destsize - 1; + } + do + { + if (!--n) + { + dest[s] = '\0'; + return; + } + *++q = *++p; + } while (*q); + } + } + + void I_strcpy(char* dest, std::size_t destsize, const char* src) + { + I_strncpyz_s(dest, destsize, src, destsize); + } + #pragma optimize("", off) __declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/) { diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 5350e425..3fb14c97 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -834,4 +834,7 @@ namespace Game bool ApplyTokenToField(unsigned int fieldNum, const char* token, visionSetVars_t* settings); int SEH_GetLocalizedTokenReference(char* token, const char* reference, const char* messageType, msgLocErrType_t errType); + + void I_strncpyz_s(char* dest, std::size_t destsize, const char* src, std::size_t count); + void I_strcpy(char* dest, std::size_t destsize, const char* src); }