From 819b3aeb160c835723bae68919d88edea6e40a0f Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 4 Jul 2023 23:01:13 +0200 Subject: [PATCH] Move and rename 'IsValidUTF8', 'UTF8CharLength' Moved to strtools (tier1); utility will be renamed and decoupled into 'stl_utility' soon. --- r5dev/engine/client/client.cpp | 3 +- r5dev/engine/server/server.cpp | 5 +- r5dev/public/tier0/utility.h | 2 - r5dev/public/tier1/strtools.h | 3 ++ r5dev/tier0/utility.cpp | 78 ------------------------------- r5dev/tier1/strtools.cpp | 84 +++++++++++++++++++++++++++++++++- 6 files changed, 90 insertions(+), 85 deletions(-) diff --git a/r5dev/engine/client/client.cpp b/r5dev/engine/client/client.cpp index 038f23a9..422ba76b 100644 --- a/r5dev/engine/client/client.cpp +++ b/r5dev/engine/client/client.cpp @@ -10,6 +10,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" #include "tier1/cvar.h" +#include "tier1/strtools.h" #include "engine/server/server.h" #include "engine/client/client.h" @@ -394,7 +395,7 @@ bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg) // Just skip if the cmd pointer is null, we still check if the // client sent too many commands and take appropriate actions. // The internal function discards the command if it's null. - if (pCmd && !IsValidUTF8(pCmd)) + if (pCmd && !V_IsValidUTF8(pCmd)) { Warning(eDLL_T::SERVER, "Removing client '%s' from slot #%i ('%llu' sent invalid string command!)\n", pClient_Adj->GetNetChan()->GetAddress(), pClient_Adj->GetUserID(), pClient_Adj->GetNucleusID()); diff --git a/r5dev/engine/server/server.cpp b/r5dev/engine/server/server.cpp index 16a53666..d8eea189 100644 --- a/r5dev/engine/server/server.cpp +++ b/r5dev/engine/server/server.cpp @@ -11,13 +11,14 @@ #include "core/stdafx.h" #include "common/protocol.h" #include "tier1/cvar.h" +#include "tier1/strtools.h" #include "engine/server/sv_main.h" #include "engine/server/server.h" #include "networksystem/pylon.h" #include "networksystem/bansystem.h" #include "ebisusdk/EbisuSDK.h" #include "public/edict.h" -#include +#include "pluginsystem/pluginsystem.h" //--------------------------------------------------------------------------------- // Purpose: Gets the number of human players on the server @@ -105,7 +106,7 @@ CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge) pszAddresBuffer, nPort, nNucleusID); // Only proceed connection if the client's name is valid and UTF-8 encoded. - if (!VALID_CHARSTAR(pszPersonaName) || !IsValidUTF8(pszPersonaName) || !IsValidPersonaName(pszPersonaName)) + if (!VALID_CHARSTAR(pszPersonaName) || !V_IsValidUTF8(pszPersonaName) || !IsValidPersonaName(pszPersonaName)) { pServer->RejectConnection(pServer->m_Socket, &pChallenge->netAdr, "#Valve_Reject_Invalid_Name"); if (bEnableLogging) diff --git a/r5dev/public/tier0/utility.h b/r5dev/public/tier0/utility.h index 291c2337..425f4750 100644 --- a/r5dev/public/tier0/utility.h +++ b/r5dev/public/tier0/utility.h @@ -44,8 +44,6 @@ string Base64Decode(const string& svInput); string UTF8Encode(const wstring& wsvInput); //string UTF8Decode(const string& svInput); -size_t UTF8CharLength(const uint8_t cInput); -bool IsValidUTF8(const char* pszString); bool StringIsDigit(const string& svInput); bool CompareStringAlphabetically(const string& svA, const string& svB); diff --git a/r5dev/public/tier1/strtools.h b/r5dev/public/tier1/strtools.h index f19b67ee..9d7604c3 100644 --- a/r5dev/public/tier1/strtools.h +++ b/r5dev/public/tier1/strtools.h @@ -70,6 +70,9 @@ int64_t V_StrTrim(char* pStr); int V_UTF8ToUnicode(const char* pUTF8, wchar_t* pwchDest, int cubDestSizeInBytes); int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes); +int V_UTF8CharLength(const unsigned char input); +bool V_IsValidUTF8(const char* pszString); + typedef enum { PATTERN_NONE = 0x00000000, diff --git a/r5dev/tier0/utility.cpp b/r5dev/tier0/utility.cpp index dc996b03..eb495ba9 100644 --- a/r5dev/tier0/utility.cpp +++ b/r5dev/tier0/utility.cpp @@ -558,84 +558,6 @@ string UTF8Encode(const wstring& wsvInput) // return ""; //} -/////////////////////////////////////////////////////////////////////////////// -// For obtaining UTF-8 character length. -size_t UTF8CharLength(const uint8_t cInput) -{ - if ((cInput & 0xFE) == 0xFC) - return 6; - if ((cInput & 0xFC) == 0xF8) - return 5; - if ((cInput & 0xF8) == 0xF0) - return 4; - else if ((cInput & 0xF0) == 0xE0) - return 3; - else if ((cInput & 0xE0) == 0xC0) - return 2; - return 1; -} - -/////////////////////////////////////////////////////////////////////////////// -// For checking if input string is a valid UTF-8 encoded string. -bool IsValidUTF8(const char* pszString) -{ - char c; - const char* it; - - while (true) - { - while (true) - { - c = *pszString; - it = pszString++; - if (c < 0) - { - break; - } - if (!c) - { - return true; - } - } - - char s = *pszString; - if ((*pszString & 0xC0) != 0x80) - { - break; - } - - pszString = it + 2; - if (c >= 0xE0u) - { - int n = (*pszString & 0x3F) | (((s & 0x3F) | ((c & 0xF) << 6)) << 6); - if ((*pszString & 0xC0) != 0x80) - { - return false; - } - - pszString = it + 3; - if (c >= 0xF0u) - { - if ((*pszString & 0xC0) != 0x80 || ((n << 6) | (*pszString & 0x3Fu)) > 0x10FFFF) - { - return false; - } - - pszString = it + 4; - } - else if ((n - 0xD800) <= 0x7FF) - { - return false; - } - } - else if (c < 0xC2u) - { - return false; - } - } - return false; -} - /////////////////////////////////////////////////////////////////////////////// // For checking if a string is a number. bool StringIsDigit(const string& svInput) diff --git a/r5dev/tier1/strtools.cpp b/r5dev/tier1/strtools.cpp index 340b0d75..ecb38482 100644 --- a/r5dev/tier1/strtools.cpp +++ b/r5dev/tier1/strtools.cpp @@ -202,7 +202,7 @@ int64_t V_StrTrim(char* pStr) } //----------------------------------------------------------------------------- -// Purpose: Converts a UTF8 string into a unicode string +// Purpose: Converts a UTF-8 string into a unicode string //----------------------------------------------------------------------------- int V_UTF8ToUnicode(const char* pUTF8, wchar_t* pwchDest, int cubDestSizeInBytes) { @@ -220,7 +220,7 @@ int V_UTF8ToUnicode(const char* pUTF8, wchar_t* pwchDest, int cubDestSizeInBytes } //----------------------------------------------------------------------------- -// Purpose: Converts a unicode string into a UTF8 (standard) string +// Purpose: Converts a unicode string into a UTF-8 (standard) string //----------------------------------------------------------------------------- int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes) { @@ -241,6 +241,86 @@ int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes return cchResult; } +//----------------------------------------------------------------------------- +// Purpose: Returns the UTF-8 character length +//----------------------------------------------------------------------------- +int V_UTF8CharLength(const unsigned char input) +{ + if ((input & 0xFE) == 0xFC) + return 6; + if ((input & 0xFC) == 0xF8) + return 5; + if ((input & 0xF8) == 0xF0) + return 4; + else if ((input & 0xF0) == 0xE0) + return 3; + else if ((input & 0xE0) == 0xC0) + return 2; + return 1; +} + +//----------------------------------------------------------------------------- +// Purpose: Checks if a given string only contains UTF-8 characters +//----------------------------------------------------------------------------- +bool V_IsValidUTF8(const char* pszString) +{ + char c; + const char* it; + + while (true) + { + while (true) + { + c = *pszString; + it = pszString++; + if (c < 0) + { + break; + } + if (!c) + { + return true; + } + } + + char s = *pszString; + if ((*pszString & 0xC0) != 0x80) + { + break; + } + + pszString = it + 2; + if (c >= 0xE0u) + { + int n = (*pszString & 0x3F) | (((s & 0x3F) | ((c & 0xF) << 6)) << 6); + if ((*pszString & 0xC0) != 0x80) + { + return false; + } + + pszString = it + 3; + if (c >= 0xF0u) + { + if ((*pszString & 0xC0) != 0x80 || ((n << 6) | (*pszString & 0x3Fu)) > 0x10FFFF) + { + return false; + } + + pszString = it + 4; + } + else if ((n - 0xD800) <= 0x7FF) + { + return false; + } + } + else if (c < 0xC2u) + { + return false; + } + } + return false; +} + bool V_StringMatchesPattern(const char* pszSource, const char* pszPattern, int nFlags /*= 0 */) { bool bExact = true;