[Bug Fix] Fix miscellaneous memory leaks related to EQApplicationPacket and it's pBuffer (#2262)

* Delete EQApplicationPacket after use

* Correct issue where Creating EQApplicationPackets in zone/mob.cpp may not free pBuffer[]

* Handle freeing pBuffer[] if exists in zone/mob.cpp Create*Packet functions

* Handle freeing pBuffer[] in zone/object.cpp Create*Packet methods

* Delete leaked outapp variables in zone/trading.cpp

* Make CreateHorseSpawnPacket() safer by freeing pBuffer[] before replacing with new[]

* Prevent initial new ServerPacket from being leaked in command_reload

* Free pack after sending in command_setlsinfo

* Delete new NPC in command_viewnpctype after printing stats

* Fix compile error

* Delete EQApplicationPacket after sending in command_kick

* Remove unneeded safe_delete(outapp) after FastQueuePacket and fix minor whitespace issue

* Delete packet after sending in WorldServer::SendReloadTasks

* Cleanup logic and free leaked NPCType in Client::Doppelganger

* Free RespawnOption in Client::HandleRespawnFromHover in 'unexpected rez from hover request' branch

* Free EQApplicationPacket after sending in Bot::ProcessBotInspectionRequest

* Free Bot when returning from failed Bot::Save() in helper_bot_create()

* Initialize variable to nullptr to prevent garbage initial value

* Undo change in other PR
This commit is contained in:
Quintinon 2022-07-02 20:10:51 -07:00 committed by GitHub
parent 5c60913583
commit b5c4357de2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 46 additions and 39 deletions

View File

@ -8797,6 +8797,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
strcpy(insr->text, inspectedBot->GetInspectMessage().text); strcpy(insr->text, inspectedBot->GetInspectMessage().text);
client->QueuePacket(outapp); // Send answer to requester client->QueuePacket(outapp); // Send answer to requester
safe_delete(outapp);
} }
} }

View File

@ -5123,7 +5123,7 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
} }
void bot_command_view_combos(Client *c, const Seperator *sep) void bot_command_view_combos(Client *c, const Seperator *sep)
{ {
const std::string class_substrs[17] = { "", const std::string class_substrs[17] = { "",
"%u (WAR)", "%u (CLR)", "%u (PAL)", "%u (RNG)", "%u (WAR)", "%u (CLR)", "%u (PAL)", "%u (RNG)",
"%u (SHD)", "%u (DRU)", "%u (MNK)", "%u (BRD)", "%u (SHD)", "%u (DRU)", "%u (MNK)", "%u (BRD)",
@ -5375,7 +5375,7 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
EQ::textures::armorLegs, EQ::textures::armorLegs,
EQ::textures::armorFeet EQ::textures::armorFeet
); );
if (helper_command_alias_fail(c, "bot_subcommand_bot_dye_armor", sep->arg[0], "botdyearmor")) { if (helper_command_alias_fail(c, "bot_subcommand_bot_dye_armor", sep->arg[0], "botdyearmor")) {
return; return;
} }
@ -5943,7 +5943,7 @@ void bot_subcommand_bot_list(Client *c, const Seperator *sep)
false, false,
bots_iter.Name bots_iter.Name
); );
c->Message( c->Message(
Chat::White, Chat::White,
fmt::format( fmt::format(
@ -6333,7 +6333,7 @@ void bot_subcommand_bot_stance(Client *c, const Seperator *sep)
bool current_flag = false; bool current_flag = false;
auto bst = EQ::constants::stanceUnknown; auto bst = EQ::constants::stanceUnknown;
if (!strcasecmp(sep->arg[1], "current")) if (!strcasecmp(sep->arg[1], "current"))
current_flag = true; current_flag = true;
else if (sep->IsNumber(1)) { else if (sep->IsNumber(1)) {
@ -7317,7 +7317,7 @@ void bot_subcommand_botgroup_list(Client *c, const Seperator *sep)
(botgroup_count + 1), (botgroup_count + 1),
botgroups_iter.first, botgroups_iter.first,
botgroups_iter.second, botgroups_iter.second,
database.botdb.IsBotGroupAutoSpawn(botgroups_iter.first) ? " (Auto Spawn)" : "", database.botdb.IsBotGroupAutoSpawn(botgroups_iter.first) ? " (Auto Spawn)" : "",
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("^botgroupload {}", botgroups_iter.first), fmt::format("^botgroupload {}", botgroups_iter.first),
false, false,
@ -9389,6 +9389,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
if (!my_bot->Save()) { if (!my_bot->Save()) {
bot_owner->Message(Chat::White, "Failed to create '%s' due to unknown cause", my_bot->GetCleanName()); bot_owner->Message(Chat::White, "Failed to create '%s' due to unknown cause", my_bot->GetCleanName());
safe_delete(my_bot);
return bot_id; return bot_id;
} }

View File

@ -6517,8 +6517,6 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
} }
made_npc->loottable_id = 0; made_npc->loottable_id = 0;
npc_type = made_npc;
int summon_count = pet.count; int summon_count = pet.count;
if(summon_count > MAX_SWARM_PETS) if(summon_count > MAX_SWARM_PETS)
@ -6531,14 +6529,11 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
}; };
while(summon_count > 0) { while(summon_count > 0) {
NPCType *npc_dup = nullptr; auto npc_type_copy = new NPCType;
if(made_npc != nullptr) { memcpy(npc_type_copy, made_npc, sizeof(NPCType));
npc_dup = new NPCType;
memcpy(npc_dup, made_npc, sizeof(NPCType));
}
NPC* swarm_pet_npc = new NPC( NPC* swarm_pet_npc = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer npc_type_copy,
0, 0,
GetPosition() + glm::vec4(swarmPetLocations[summon_count - 1], 0.0f, 0.0f), GetPosition() + glm::vec4(swarmPetLocations[summon_count - 1], 0.0f, 0.0f),
GravityBehavior::Water); GravityBehavior::Water);
@ -6563,12 +6558,13 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
swarm_pet_npc->GetSwarmInfo()->target = 0; swarm_pet_npc->GetSwarmInfo()->target = 0;
//we allocated a new NPC type object, give the NPC ownership of that memory //we allocated a new NPC type object, give the NPC ownership of that memory
if(npc_dup != nullptr) swarm_pet_npc->GiveNPCTypeData(npc_type_copy);
swarm_pet_npc->GiveNPCTypeData(npc_dup);
entity_list.AddNPC(swarm_pet_npc); entity_list.AddNPC(swarm_pet_npc);
summon_count--; summon_count--;
} }
safe_delete(made_npc);
} }
void Client::AssignToInstance(uint16 instance_id) void Client::AssignToInstance(uint16 instance_id)

View File

@ -2053,6 +2053,7 @@ void Client::HandleRespawnFromHover(uint32 Option)
if (PendingRezzXP < 0 || PendingRezzSpellID == 0) if (PendingRezzXP < 0 || PendingRezzSpellID == 0)
{ {
LogSpells("Unexpected Rezz from hover request"); LogSpells("Unexpected Rezz from hover request");
safe_delete(default_to_bind);
return; return;
} }
SetHP(GetMaxHP() / 5); SetHP(GetMaxHP() / 5);

View File

@ -17,6 +17,7 @@ void command_kick(Client *c, const Seperator *sep)
if (client->Admin() <= c->Admin()) { if (client->Admin() <= c->Admin()) {
auto outapp = new EQApplicationPacket(OP_GMKick, 0); auto outapp = new EQApplicationPacket(OP_GMKick, 0);
client->QueuePacket(outapp); client->QueuePacket(outapp);
safe_delete(outapp);
client->Kick("Ordered kicked by command"); client->Kick("Ordered kicked by command");
c->Message( c->Message(
Chat::White, Chat::White,

View File

@ -1122,8 +1122,8 @@ void command_object(Client *c, const Seperator *sep)
app = new EQApplicationPacket(); app = new EQApplicationPacket();
o->CreateDeSpawnPacket(app); o->CreateDeSpawnPacket(app);
entity_list.QueueClients(nullptr, app); entity_list.QueueClients(nullptr, app);
entity_list.RemoveObject(o->GetID()); entity_list.RemoveObject(o->GetID());
safe_delete(app);
// Verifying ZoneID and Version in case someone else ended up adding an object with our ID // Verifying ZoneID and Version in case someone else ended up adding an object with our ID
// from a different zone/version. Don't want to delete someone else's work. // from a different zone/version. Don't want to delete someone else's work.

View File

@ -61,7 +61,7 @@ void command_reload(Client *c, const Seperator *sep)
return; return;
} }
auto pack = new ServerPacket; ServerPacket* pack = nullptr;
if (is_aa) { if (is_aa) {
c->Message(Chat::White, "Attempting to reload Alternate Advancement Data globally."); c->Message(Chat::White, "Attempting to reload Alternate Advancement Data globally.");
@ -282,7 +282,7 @@ void command_reload(Client *c, const Seperator *sep)
pack = new ServerPacket(ServerOP_ReloadZonePoints, 0); pack = new ServerPacket(ServerOP_ReloadZonePoints, 0);
} }
if (pack->opcode) { if (pack) {
worldserver.SendPacket(pack); worldserver.SendPacket(pack);
} }

View File

@ -18,6 +18,7 @@ void command_setlsinfo(Client *c, const Seperator *sep)
strn0cpy(s->user_email, sep->arg[1], 100); strn0cpy(s->user_email, sep->arg[1], 100);
strn0cpy(s->userpassword, sep->arg[2], 50); strn0cpy(s->userpassword, sep->arg[2], 50);
worldserver.SendPacket(pack); worldserver.SendPacket(pack);
safe_delete(pack);
c->Message(Chat::White, "Your email and local loginserver password have been set."); c->Message(Chat::White, "Your email and local loginserver password have been set.");
} }

View File

@ -13,6 +13,7 @@ void command_viewnpctype(Client *c, const Seperator *sep)
GravityBehavior::Water GravityBehavior::Water
); );
npc->ShowStats(c); npc->ShowStats(c);
safe_delete(npc);
} }
else { else {
c->Message( c->Message(

View File

@ -174,6 +174,7 @@ void Client::SetHorseId(uint16 horseid_in) {
void Mob::CreateHorseSpawnPacket(EQApplicationPacket* app, const char* ownername, uint16 ownerid, Mob* ForWho) { void Mob::CreateHorseSpawnPacket(EQApplicationPacket* app, const char* ownername, uint16 ownerid, Mob* ForWho) {
app->SetOpcode(OP_NewSpawn); app->SetOpcode(OP_NewSpawn);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[sizeof(NewSpawn_Struct)]; app->pBuffer = new uchar[sizeof(NewSpawn_Struct)];
app->size = sizeof(NewSpawn_Struct); app->size = sizeof(NewSpawn_Struct);
memset(app->pBuffer, 0, sizeof(NewSpawn_Struct)); memset(app->pBuffer, 0, sizeof(NewSpawn_Struct));

View File

@ -1158,6 +1158,7 @@ void Mob::CreateSpawnPacket(EQApplicationPacket *app, Mob *ForWho)
{ {
app->SetOpcode(OP_NewSpawn); app->SetOpcode(OP_NewSpawn);
app->size = sizeof(NewSpawn_Struct); app->size = sizeof(NewSpawn_Struct);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[app->size]; app->pBuffer = new uchar[app->size];
memset(app->pBuffer, 0, app->size); memset(app->pBuffer, 0, app->size);
auto ns = (NewSpawn_Struct *) app->pBuffer; auto ns = (NewSpawn_Struct *) app->pBuffer;
@ -1175,7 +1176,7 @@ void Mob::CreateSpawnPacket(EQApplicationPacket *app, Mob *ForWho)
void Mob::CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns) { void Mob::CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns) {
app->SetOpcode(OP_NewSpawn); app->SetOpcode(OP_NewSpawn);
app->size = sizeof(NewSpawn_Struct); app->size = sizeof(NewSpawn_Struct);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[sizeof(NewSpawn_Struct)]; app->pBuffer = new uchar[sizeof(NewSpawn_Struct)];
// Copy ns directly into packet // Copy ns directly into packet
@ -1367,6 +1368,7 @@ void Mob::CreateDespawnPacket(EQApplicationPacket* app, bool Decay)
{ {
app->SetOpcode(OP_DeleteSpawn); app->SetOpcode(OP_DeleteSpawn);
app->size = sizeof(DeleteSpawn_Struct); app->size = sizeof(DeleteSpawn_Struct);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[app->size]; app->pBuffer = new uchar[app->size];
memset(app->pBuffer, 0, app->size); memset(app->pBuffer, 0, app->size);
DeleteSpawn_Struct* ds = (DeleteSpawn_Struct*)app->pBuffer; DeleteSpawn_Struct* ds = (DeleteSpawn_Struct*)app->pBuffer;
@ -1380,6 +1382,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
IsFullHP=(current_hp>=max_hp); IsFullHP=(current_hp>=max_hp);
app->SetOpcode(OP_MobHealth); app->SetOpcode(OP_MobHealth);
app->size = sizeof(SpawnHPUpdate_Struct2); app->size = sizeof(SpawnHPUpdate_Struct2);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[app->size]; app->pBuffer = new uchar[app->size];
memset(app->pBuffer, 0, sizeof(SpawnHPUpdate_Struct2)); memset(app->pBuffer, 0, sizeof(SpawnHPUpdate_Struct2));
SpawnHPUpdate_Struct2* ds = (SpawnHPUpdate_Struct2*)app->pBuffer; SpawnHPUpdate_Struct2* ds = (SpawnHPUpdate_Struct2*)app->pBuffer;

View File

@ -412,6 +412,7 @@ EQ::ItemInstance* Object::PopItem(uint8 index)
void Object::CreateSpawnPacket(EQApplicationPacket* app) void Object::CreateSpawnPacket(EQApplicationPacket* app)
{ {
app->SetOpcode(OP_GroundSpawn); app->SetOpcode(OP_GroundSpawn);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[sizeof(Object_Struct)]; app->pBuffer = new uchar[sizeof(Object_Struct)];
app->size = sizeof(Object_Struct); app->size = sizeof(Object_Struct);
memcpy(app->pBuffer, &m_data, sizeof(Object_Struct)); memcpy(app->pBuffer, &m_data, sizeof(Object_Struct));
@ -420,6 +421,7 @@ void Object::CreateSpawnPacket(EQApplicationPacket* app)
void Object::CreateDeSpawnPacket(EQApplicationPacket* app) void Object::CreateDeSpawnPacket(EQApplicationPacket* app)
{ {
app->SetOpcode(OP_ClickObject); app->SetOpcode(OP_ClickObject);
safe_delete_array(app->pBuffer);
app->pBuffer = new uchar[sizeof(ClickObject_Struct)]; app->pBuffer = new uchar[sizeof(ClickObject_Struct)];
app->size = sizeof(ClickObject_Struct); app->size = sizeof(ClickObject_Struct);
memset(app->pBuffer, 0, sizeof(ClickObject_Struct)); memset(app->pBuffer, 0, sizeof(ClickObject_Struct));

View File

@ -1078,6 +1078,7 @@ void Client::Trader_CustomerBrowsing(Client *Customer) {
sis->TraderID = Customer->GetID(); sis->TraderID = Customer->GetID();
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp);
} }
@ -1151,8 +1152,8 @@ void Client::Trader_EndTrader() {
} }
safe_delete(outapp); safe_delete(outapp);
safe_delete(gis);
} }
safe_delete(gis);
} }
database.DeleteTraderItem(CharacterID()); database.DeleteTraderItem(CharacterID());
@ -2584,6 +2585,7 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) {
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp);
} }
} }

View File

@ -3416,6 +3416,7 @@ void WorldServer::SendReloadTasks(uint8 reload_type, uint32 task_id) {
rts->task_id = task_id; rts->task_id = task_id;
SendPacket(pack); SendPacket(pack);
safe_delete(pack);
} }
void WorldServer::HandleReloadTasks(ServerPacket *pack) void WorldServer::HandleReloadTasks(ServerPacket *pack)

View File

@ -491,21 +491,21 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
} else { } else {
// vesuvias - zoneing to another zone so we need to the let the world server // vesuvias - zoneing to another zone so we need to the let the world server
//handle things with the client for a while //handle things with the client for a while
auto pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct)); auto pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct));
ZoneToZone_Struct *ztz = (ZoneToZone_Struct *)pack->pBuffer; ZoneToZone_Struct *ztz = (ZoneToZone_Struct *)pack->pBuffer;
ztz->response = 0; ztz->response = 0;
ztz->current_zone_id = zone->GetZoneID(); ztz->current_zone_id = zone->GetZoneID();
ztz->current_instance_id = zone->GetInstanceID(); ztz->current_instance_id = zone->GetInstanceID();
ztz->requested_zone_id = zone_id; ztz->requested_zone_id = zone_id;
ztz->requested_instance_id = instance_id; ztz->requested_instance_id = instance_id;
ztz->admin = admin; ztz->admin = admin;
ztz->ignorerestrictions = ignore_r; ztz->ignorerestrictions = ignore_r;
strcpy(ztz->name, GetName()); strcpy(ztz->name, GetName());
ztz->guild_id = GuildID(); ztz->guild_id = GuildID();
worldserver.SendPacket(pack); worldserver.SendPacket(pack);
safe_delete(pack); safe_delete(pack);
} }
//reset to unsolicited. //reset to unsolicited.
@ -778,7 +778,6 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
outapp->priority = 6; outapp->priority = 6;
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
safe_delete(outapp);
} }
else if(zm == ZoneSolicited || zm == ZoneToSafeCoords) { else if(zm == ZoneSolicited || zm == ZoneToSafeCoords) {
auto outapp = auto outapp =
@ -795,7 +794,6 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
outapp->priority = 6; outapp->priority = 6;
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
safe_delete(outapp);
} }
else if(zm == EvacToSafeCoords) { else if(zm == EvacToSafeCoords) {
auto outapp = auto outapp =
@ -829,7 +827,6 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
outapp->priority = 6; outapp->priority = 6;
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
safe_delete(outapp);
} }
else { else {
if(zoneID == GetZoneID()) { if(zoneID == GetZoneID()) {
@ -854,7 +851,6 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
gmg->type = 0x01; //an observed value, not sure of meaning gmg->type = 0x01; //an observed value, not sure of meaning
outapp->priority = 6; outapp->priority = 6;
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
safe_delete(outapp);
} }
LogDebug("Player [{}] has requested a zoning to LOC x=[{}], y=[{}], z=[{}], heading=[{}] in zoneid=[{}]", GetName(), x, y, z, heading, zoneID); LogDebug("Player [{}] has requested a zoning to LOC x=[{}], y=[{}], z=[{}], heading=[{}] in zoneid=[{}]", GetName(), x, y, z, heading, zoneID);