From fd0175b981112414f17c6be96e38e808839c3192 Mon Sep 17 00:00:00 2001 From: Meltie2013 Date: Thu, 30 Jun 2022 08:33:46 +0100 Subject: [PATCH] Properly normalize string to UTF-8 --- src/game/ChatCommands/BanAndKickCommands.cpp | 5 ++- src/game/ChatCommands/LookupCommands.cpp | 5 ++- src/game/WorldHandlers/AccountMgr.cpp | 41 ++++---------------- src/game/WorldHandlers/AccountMgr.h | 3 -- src/game/WorldHandlers/Chat.cpp | 2 +- src/modules/Eluna | 2 +- src/shared/Utilities/Util.cpp | 13 +++++++ src/shared/Utilities/Util.h | 8 ++++ 8 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/game/ChatCommands/BanAndKickCommands.cpp b/src/game/ChatCommands/BanAndKickCommands.cpp index 66a83356..577026d4 100644 --- a/src/game/ChatCommands/BanAndKickCommands.cpp +++ b/src/game/ChatCommands/BanAndKickCommands.cpp @@ -27,6 +27,7 @@ #include "World.h" #include "AccountMgr.h" #include "Util.h" +#include "ObjectMgr.h" /********************************************************************** CommandTable : banCommandTable @@ -150,7 +151,7 @@ bool ChatHandler::HandleBanHelper(BanMode mode, char* args) switch (mode) { case BAN_ACCOUNT: - if (!AccountMgr::normalizeString(nameOrIP)) + if (!Utf8ToUpperOnlyLatin(nameOrIP)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); SetSentErrorMessage(true); @@ -487,7 +488,7 @@ bool ChatHandler::HandleUnBanHelper(BanMode mode, char* args) switch (mode) { case BAN_ACCOUNT: - if (!AccountMgr::normalizeString(nameOrIP)) + if (!Utf8ToUpperOnlyLatin(nameOrIP)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); SetSentErrorMessage(true); diff --git a/src/game/ChatCommands/LookupCommands.cpp b/src/game/ChatCommands/LookupCommands.cpp index cd96f487..19a8b06c 100644 --- a/src/game/ChatCommands/LookupCommands.cpp +++ b/src/game/ChatCommands/LookupCommands.cpp @@ -29,6 +29,7 @@ #include "World.h" #include "ObjectMgr.h" #include "SQLStorages.h" +#include "Util.h" /********************************************************************** CommandTable : lookupCommandTable @@ -503,7 +504,7 @@ bool ChatHandler::HandleLookupAccountNameCommand(char* args) } std::string account = accountStr; - if (!AccountMgr::normalizeString(account)) + if (!Utf8ToUpperOnlyLatin(account)) { return false; } @@ -610,7 +611,7 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(char* args) } std::string account = accountStr; - if (!AccountMgr::normalizeString(account)) + if (!Utf8ToUpperOnlyLatin(account)) { return false; } diff --git a/src/game/WorldHandlers/AccountMgr.cpp b/src/game/WorldHandlers/AccountMgr.cpp index 4867ad6f..8eae33f0 100644 --- a/src/game/WorldHandlers/AccountMgr.cpp +++ b/src/game/WorldHandlers/AccountMgr.cpp @@ -67,8 +67,8 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass return AOR_PASS_TOO_LONG; // password too long } - normalizeString(username); - normalizeString(password); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(password); if (GetId(username)) { @@ -168,8 +168,8 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, return AOR_PASS_TOO_LONG; } - normalizeString(new_uname); - normalizeString(new_passwd); + Utf8ToUpperOnlyLatin(new_uname); + Utf8ToUpperOnlyLatin(new_passwd); std::string safe_new_uname = new_uname; LoginDatabase.escape_string(safe_new_uname); @@ -205,8 +205,8 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd) return AOR_PASS_TOO_LONG; } - normalizeString(username); - normalizeString(new_passwd); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(new_passwd); // also reset s and v to force update at next realmd login if (!LoginDatabase.PExecute("UPDATE `account` SET `v`='0', `s`='0', `sha_pass_hash`='%s' WHERE `id`='%u'", @@ -322,8 +322,8 @@ bool AccountMgr::CheckPassword(uint32 accid, std::string passwd) return false; } - normalizeString(passwd); - normalizeString(username); + Utf8ToUpperOnlyLatin(passwd); + Utf8ToUpperOnlyLatin(username); QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM `account` WHERE `id`='%u' AND `sha_pass_hash`='%s'", accid, CalculateShaPassHash(username, passwd).c_str()); if (result) @@ -335,31 +335,6 @@ bool AccountMgr::CheckPassword(uint32 accid, std::string passwd) return false; } -/** - * It converts a string to uppercase, but only if it's a latin character - * - * @param utf8str The string to be normalized. - * - * @return A boolean value. - */ -bool AccountMgr::normalizeString(std::string& utf8str) -{ - wchar_t wstr_buf[MAX_ACCOUNT_STR + 1]; - size_t wstr_len = MAX_ACCOUNT_STR; - - if (!Utf8toWStr(utf8str, wstr_buf, wstr_len)) - { - return false; - } - - for (uint32 i = 0; i <= wstr_len; ++i) - { - wstr_buf[i] = wcharToUpperOnlyLatin(wstr_buf[i]); - } - - return WStrToUtf8(wstr_buf, wstr_len, utf8str); -} - /** * It takes a username and password, concatenates them with a colon, and then hashes the result with * SHA1 diff --git a/src/game/WorldHandlers/AccountMgr.h b/src/game/WorldHandlers/AccountMgr.h index 91f0b679..8a32cba0 100644 --- a/src/game/WorldHandlers/AccountMgr.h +++ b/src/game/WorldHandlers/AccountMgr.h @@ -59,11 +59,8 @@ class AccountMgr bool GetName(uint32 acc_id, std::string& name); uint32 GetCharactersCount(uint32 acc_id); std::string CalculateShaPassHash(std::string& name, std::string& password); - - static bool normalizeString(std::string& utf8str); }; /* A macro that creates a global variable called `sAccountMgr` that is an instance of the `AccountMgr` class. */ #define sAccountMgr MaNGOS::Singleton::Instance() - #endif diff --git a/src/game/WorldHandlers/Chat.cpp b/src/game/WorldHandlers/Chat.cpp index 47ee373c..3e28803e 100644 --- a/src/game/WorldHandlers/Chat.cpp +++ b/src/game/WorldHandlers/Chat.cpp @@ -3570,7 +3570,7 @@ uint32 ChatHandler::ExtractAccountId(char** args, std::string* accountName /*= N else { account_name = account_str; - if (!AccountMgr::normalizeString(account_name)) + if (!Utf8ToUpperOnlyLatin(account_name)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str()); SetSentErrorMessage(true); diff --git a/src/modules/Eluna b/src/modules/Eluna index c7b51c22..8c648614 160000 --- a/src/modules/Eluna +++ b/src/modules/Eluna @@ -1 +1 @@ -Subproject commit c7b51c226f78088bbe51c129ca41c03728634b45 +Subproject commit 8c648614e143948b2b2da76bef759d90542ae975 diff --git a/src/shared/Utilities/Util.cpp b/src/shared/Utilities/Util.cpp index a6177dc1..a7a101f6 100644 --- a/src/shared/Utilities/Util.cpp +++ b/src/shared/Utilities/Util.cpp @@ -415,6 +415,19 @@ void utf8truncate(std::string& utf8str, size_t len) } } +bool Utf8ToUpperOnlyLatin(std::string& utf8String) +{ + std::wstring wstr; + if (!Utf8toWStr(utf8String, wstr)) + { + return false; + } + + std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin); + + return WStrToUtf8(wstr, utf8String); +} + size_t utf8limit(std::string& utf8str, size_t bytes) { if (utf8str.size() > bytes) diff --git a/src/shared/Utilities/Util.h b/src/shared/Utilities/Util.h index 4ecebd12..55886fd1 100644 --- a/src/shared/Utilities/Util.h +++ b/src/shared/Utilities/Util.h @@ -288,6 +288,14 @@ inline void ApplyPercentModFloatVar(float& var, float val, bool apply) var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val)); } +/** + * @brief + * + * @param utf8String + * @return bool + */ +bool Utf8ToUpperOnlyLatin(std::string& utf8String); + /** * @brief *