From 4358e24dab6cded6c885881af2c3cd2c2216af9c Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 27 Apr 2021 19:53:34 -0400 Subject: [PATCH] [Bug Fix] Fix use-after-free corruption with some DB calls (#1335) --- common/database.cpp | 20 ++++++++++++-------- common/database.h | 4 ++-- zone/embparser_api.cpp | 7 ++++--- zone/lua_general.cpp | 4 ++-- zone/questmgr.cpp | 14 ++++++++------ zone/questmgr.h | 4 ++-- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index a75c65480..385f07c18 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -870,36 +870,40 @@ void Database::GetCharName(uint32 char_id, char* name) { } } -const char* Database::GetCharNameByID(uint32 char_id) { +std::string Database::GetCharNameByID(uint32 char_id) { std::string query = fmt::format("SELECT `name` FROM `character_data` WHERE id = {}", char_id); auto results = QueryDatabase(query); + std::string res; if (!results.Success()) { - return ""; + return res; } if (results.RowCount() == 0) { - return ""; + return res; } auto row = results.begin(); - return row[0]; + res = row[0]; + return res; } -const char* Database::GetNPCNameByID(uint32 npc_id) { +std::string Database::GetNPCNameByID(uint32 npc_id) { std::string query = fmt::format("SELECT `name` FROM `npc_types` WHERE id = {}", npc_id); auto results = QueryDatabase(query); + std::string res; if (!results.Success()) { - return ""; + return res; } if (results.RowCount() == 0) { - return ""; + return res; } auto row = results.begin(); - return row[0]; + res = row[0]; + return res; } bool Database::LoadVariables() { diff --git a/common/database.h b/common/database.h index c15e200bc..f6d93d5aa 100644 --- a/common/database.h +++ b/common/database.h @@ -138,8 +138,8 @@ public: void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0); void GetCharName(uint32 char_id, char* name); - const char *GetCharNameByID(uint32 char_id); - const char *GetNPCNameByID(uint32 npc_id); + std::string GetCharNameByID(uint32 char_id); + std::string GetNPCNameByID(uint32 npc_id); void LoginIP(uint32 AccountID, const char* LoginIP); /* Instancing */ diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index b95e7946e..f0ba69526 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3033,9 +3033,9 @@ XS(XS__getnpcnamebyid) { dXSTARG; uint32 npc_id = (int) SvIV(ST(0)); - const char *npc_name = quest_manager.getnpcnamebyid(npc_id); + auto npc_name = quest_manager.getnpcnamebyid(npc_id); - sv_setpv(TARG, npc_name); + sv_setpv(TARG, npc_name.c_str()); XSprePUSH; PUSHTARG; XSRETURN(1); @@ -3423,8 +3423,9 @@ XS(XS__getcharnamebyid) { Const_char *RETVAL; uint32 char_id = (int) SvUV(ST(0)); + auto name = quest_manager.getcharnamebyid(char_id); - RETVAL = quest_manager.getcharnamebyid(char_id); + RETVAL = name.c_str(); sv_setpv(TARG, RETVAL); XSprePUSH; diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index a121194be..62f0544c7 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -901,7 +901,7 @@ bool lua_delete_data(std::string bucket_key) { return DataBucket::DeleteData(bucket_key); } -const char *lua_get_char_name_by_id(uint32 char_id) { +std::string lua_get_char_name_by_id(uint32 char_id) { return database.GetCharNameByID(char_id); } @@ -937,7 +937,7 @@ int lua_get_group_id_by_char_id(uint32 char_id) { return database.GetGroupIDByCharID(char_id); } -const char *lua_get_npc_name_by_id(uint32 npc_id) { +std::string lua_get_npc_name_by_id(uint32 npc_id) { return quest_manager.getnpcnamebyid(npc_id); } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 1a1eba4fc..561f3eb3a 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2781,11 +2781,12 @@ std::string QuestManager::getitemname(uint32 item_id) { return item_name; } -const char *QuestManager::getnpcnamebyid(uint32 npc_id) { +std::string QuestManager::getnpcnamebyid(uint32 npc_id) { + std::string res; if (npc_id > 0) { - return database.GetNPCNameByID(npc_id); + res = database.GetNPCNameByID(npc_id); } - return ""; + return res; } uint16 QuestManager::CreateInstance(const char *zone, int16 version, uint32 duration) @@ -2991,11 +2992,12 @@ std::string QuestManager::saylink(char *saylink_text, bool silent, const char *l return EQ::SayLinkEngine::GenerateQuestSaylink(saylink_text, silent, link_name); } -const char* QuestManager::getcharnamebyid(uint32 char_id) { +std::string QuestManager::getcharnamebyid(uint32 char_id) { + std::string res; if (char_id > 0) { - return database.GetCharNameByID(char_id); + res = database.GetCharNameByID(char_id); } - return ""; + return res; } uint32 QuestManager::getcharidbyname(const char* name) { diff --git a/zone/questmgr.h b/zone/questmgr.h index 83ffe6f5b..95166886f 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -265,7 +265,7 @@ public: void FlagInstanceByRaidLeader(uint32 zone, int16 version); const char* varlink(char* perltext, int item_id); std::string saylink(char *saylink_text, bool silent, const char *link_name); - const char* getcharnamebyid(uint32 char_id); + std::string getcharnamebyid(uint32 char_id); uint32 getcharidbyname(const char* name); std::string getclassname(uint8 class_id, uint8 level = 0); int getcurrencyid(uint32 item_id); @@ -273,7 +273,7 @@ public: const char* getguildnamebyid(int guild_id); int getguildidbycharid(uint32 char_id); int getgroupidbycharid(uint32 char_id); - const char* getnpcnamebyid(uint32 npc_id); + std::string getnpcnamebyid(uint32 npc_id); int getraididbycharid(uint32 char_id); void SetRunning(bool val); bool IsRunning();