Skip to content

Commit

Permalink
Improve Database API to avoid memory leaks in the future, part 2.
Browse files Browse the repository at this point in the history
Given the caller takes ownership of the query result that's returned by
Database::PQuery(), let's return a unique_ptr instead of a raw pointer.
This makes the ownership clear in the API and avoids memory leaks when
the caller doesn't delete the pointer in all scenarios (think early
return or exceptions).
  • Loading branch information
evil-at-wow committed Oct 21, 2023
1 parent d636726 commit af2a4f8
Show file tree
Hide file tree
Showing 36 changed files with 535 additions and 751 deletions.
9 changes: 4 additions & 5 deletions src/game/AI/ScriptDevAI/system/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ SystemMgr& SystemMgr::Instance()
void SystemMgr::LoadVersion()
{
// Get Version information
QueryResult* result = WorldDatabase.PQuery("SELECT version FROM sd2_db_version LIMIT 1");
auto queryResult = WorldDatabase.PQuery("SELECT version FROM sd2_db_version LIMIT 1");

if (result)
if (queryResult)
{
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();

strSD2Version = fields[0].GetCppString();
delete result;
}
else
script_error_log("Missing `sd2_db_version` information.");
Expand Down Expand Up @@ -73,7 +72,7 @@ void SystemMgr::LoadScriptWaypoints()
outstring_log("SD2: Loading Script Waypoints for " UI64FMTD " creature(s)...", creatureCount);

// 0 1 2 3 4 5 6 7 8
result.reset(WorldDatabase.PQuery("SELECT Entry, PathId, Point, PositionX, PositionY, PositionZ, Orientation, WaitTime, ScriptId FROM script_waypoint ORDER BY Entry, PathId, Point"));
result = WorldDatabase.PQuery("SELECT Entry, PathId, Point, PositionX, PositionY, PositionZ, Orientation, WaitTime, ScriptId FROM script_waypoint ORDER BY Entry, PathId, Point");

if (result)
{
Expand Down
57 changes: 23 additions & 34 deletions src/game/Accounts/AccountMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,28 +72,25 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass

AccountOpResult AccountMgr::DeleteAccount(uint32 accid) const
{
QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u'", accid);
if (!result)
auto queryResult = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u'", accid);
if (!queryResult)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;

// existing characters list
result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%u'", accid);
if (result)
queryResult = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%u'", accid);
if (queryResult)
{
do
{
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();
uint32 guidlo = fields[0].GetUInt32();
ObjectGuid guid = ObjectGuid(HIGHGUID_PLAYER, guidlo);

// kick if player currently
ObjectAccessor::KickPlayer(guid);
Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
}
while (result->NextRow());

delete result;
while (queryResult->NextRow());
}

// table realm specific but common for all characters of account for realm
Expand All @@ -115,10 +112,9 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid) const

AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd) const
{
QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u'", accid);
if (!result)
auto queryResult = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u'", accid);
if (!queryResult)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;

if (utf8length(new_uname) > MAX_ACCOUNT_STR)
return AOR_NAME_TOO_LONG;
Expand Down Expand Up @@ -189,21 +185,19 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
uint32 AccountMgr::GetId(std::string username) const
{
LoginDatabase.escape_string(username);
QueryResult* result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
if (!result)
auto queryResult = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
if (!queryResult)
return 0;
uint32 id = (*result)[0].GetUInt32();
delete result;
uint32 id = (*queryResult)[0].GetUInt32();
return id;
}

AccountTypes AccountMgr::GetSecurity(uint32 acc_id)
{
QueryResult* result = LoginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
if (result)
auto queryResult = LoginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
if (queryResult)
{
AccountTypes sec = AccountTypes((*result)[0].GetInt32());
delete result;
AccountTypes sec = AccountTypes((*queryResult)[0].GetInt32());
return sec;
}

Expand All @@ -212,11 +206,10 @@ AccountTypes AccountMgr::GetSecurity(uint32 acc_id)

bool AccountMgr::GetName(uint32 acc_id, std::string& name) const
{
QueryResult* result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
if (result)
auto queryResult = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
if (queryResult)
{
name = (*result)[0].GetCppString();
delete result;
name = (*queryResult)[0].GetCppString();
return true;
}

Expand All @@ -226,12 +219,11 @@ bool AccountMgr::GetName(uint32 acc_id, std::string& name) const
uint32 AccountMgr::GetCharactersCount(uint32 acc_id) const
{
// check character count
QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%u'", acc_id);
if (result)
auto queryResult = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%u'", acc_id);
if (queryResult)
{
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();
uint32 charcount = fields[0].GetUInt32();
delete result;
return charcount;
}
return 0;
Expand All @@ -246,22 +238,19 @@ bool AccountMgr::CheckPassword(uint32 accid, std::string passwd) const
normalizeString(passwd);
normalizeString(username);

QueryResult* result = LoginDatabase.PQuery("SELECT s, v FROM account WHERE id='%u'", accid);
if (result)
auto queryResult = LoginDatabase.PQuery("SELECT s, v FROM account WHERE id='%u'", accid);
if (queryResult)
{
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();
SRP6 srp;

bool calcv = srp.CalculateVerifier(
CalculateShaPassHash(username, passwd), fields[0].GetCppString().c_str());

if (calcv && srp.ProofVerifier(fields[1].GetCppString()))
{
delete result;
return true;
}

delete result;
}

return false;
Expand Down
18 changes: 8 additions & 10 deletions src/game/AuctionHouseBot/AuctionHouseBot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ void AuctionHouseBot::Initialize()
m_buyValue = GetMinMaxConfig("AuctionHouseBot.Buy.Value", 0, 200, 90);

// overridden items
QueryResult* result = CharacterDatabase.PQuery("SELECT item, value, add_chance, min_amount, max_amount FROM ahbot_items");
if (result)
auto queryResult = CharacterDatabase.PQuery("SELECT item, value, add_chance, min_amount, max_amount FROM ahbot_items");
if (queryResult)
{
do
{
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();
uint32 itemId = fields[0].GetUInt32();
AuctionHouseBotItemData itemData;
itemData.Value = fields[1].GetUInt32();
Expand All @@ -146,8 +146,7 @@ void AuctionHouseBot::Initialize()
itemData.MaxAmount = fields[4].GetUInt32();
m_itemData[itemId] = itemData;
}
while (result->NextRow());
delete result;
while (queryResult->NextRow());
}
}
}
Expand Down Expand Up @@ -433,19 +432,18 @@ void AuctionHouseBot::ParseLootConfig(char const* fieldname, std::vector<int32>&
void AuctionHouseBot::FillUintVectorFromQuery(char const* query, std::vector<uint32>& lootTemplates)
{
lootTemplates.clear();
if (QueryResult* result = WorldDatabase.PQuery("%s", query))
if (auto queryResult = WorldDatabase.PQuery("%s", query))
{
BarGoLink bar(result->GetRowCount());
BarGoLink bar(queryResult->GetRowCount());
do
{
bar.step();
Field* fields = result->Fetch();
Field* fields = queryResult->Fetch();
uint32 entry = fields[0].GetUInt32();
if (!entry)
continue;
lootTemplates.push_back(fields[0].GetUInt32());
} while (result->NextRow());
delete result;
} while (queryResult->NextRow());
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/game/Chat/Chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,16 +792,16 @@ class ChatHandler
GameObject* GetGameObjectWithGuid(uint32 lowguid, uint32 entry) const;

// Utility methods for commands
bool ShowAccountListHelper(QueryResult* result, uint32* limit = nullptr, bool title = true, bool error = true);
bool ShowAccountListHelper(std::unique_ptr<QueryResult> queryResult, uint32* limit = nullptr, bool title = true, bool error = true);
void ShowFactionListHelper(FactionEntry const* factionEntry, LocaleConstant loc, FactionState const* repState = nullptr, Player* target = nullptr);
void ShowItemListHelper(uint32 itemId, int loc_idx, Player* target = nullptr);
void ShowQuestListHelper(uint32 questId, int32 loc_idx, Player* target = nullptr);
bool ShowPlayerListHelper(QueryResult* result, uint32* limit = nullptr, bool title = true, bool error = true);
bool ShowPlayerListHelper(std::unique_ptr<QueryResult> queryResult, uint32* limit = nullptr, bool title = true, bool error = true);
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc);
void ShowPoolListHelper(uint16 pool_id);
void ShowTriggerListHelper(AreaTriggerEntry const* atEntry);
void ShowTriggerTargetListHelper(uint32 id, AreaTrigger const* at, bool subpart = false);
bool LookupPlayerSearchCommand(QueryResult* result, uint32* limit = nullptr);
bool LookupPlayerSearchCommand(std::unique_ptr<QueryResult> queryResult, uint32* limit = nullptr);
bool HandleBanListHelper(std::unique_ptr<QueryResult> queryResult);
bool HandleBanHelper(BanMode mode, char* args);
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
Expand Down
Loading

0 comments on commit af2a4f8

Please sign in to comment.