[Crash] Pointer validation in mob iteration loops (#2490)

This commit is contained in:
Chris Miles 2022-10-15 15:10:11 -05:00 committed by GitHub
parent 05723ad1e8
commit bbbebdd346
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 4 deletions

View File

@ -443,9 +443,9 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
* Formula (all int math) * Formula (all int math)
* (posted for parry, dodge appears to be the same as confirmed per Dev, assuming Riposte/Block are the same) * (posted for parry, dodge appears to be the same as confirmed per Dev, assuming Riposte/Block are the same)
* Chance = (((SKILL + 100) + [((SKILL+100) * SPA(175).Base1) / 100]) / 45) + [(hDex / 25) - min([hStrikethrough, hDex / 25])]. * Chance = (((SKILL + 100) + [((SKILL+100) * SPA(175).Base1) / 100]) / 45) + [(hDex / 25) - min([hStrikethrough, hDex / 25])].
If an NPC's Heroic Strikethrough is higher than your character's Heroic Agility bonus, you are disqualified from the "bonus" you would have gotten at the end. If an NPC's Heroic Strikethrough is higher than your character's Heroic Agility bonus, you are disqualified from the "bonus" you would have gotten at the end.
*/ */
int hstrikethrough = attacker->GetHeroicStrikethrough(); int hstrikethrough = attacker->GetHeroicStrikethrough();
// riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo // riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo
@ -1621,6 +1621,10 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
auto& mob_list = entity_list.GetCloseMobList(other); auto& mob_list = entity_list.GetCloseMobList(other);
for (auto& e : mob_list) { for (auto& e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) { if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition()); float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) { if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
@ -2135,6 +2139,9 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
auto& mob_list = entity_list.GetCloseMobList(other); auto& mob_list = entity_list.GetCloseMobList(other);
for (auto& e : mob_list) { for (auto& e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) { if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->GetPosition(), mob->GetPosition()); float distance = Distance(other->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) { if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {

View File

@ -77,6 +77,9 @@ void Aura::ProcessOnAllFriendlies(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) { if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) {
auto it = casted_on.find(mob->GetID()); auto it = casted_on.find(mob->GetID());
@ -187,6 +190,9 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
// step 1: check if we're already managing this NPC's buff // step 1: check if we're already managing this NPC's buff
auto it = casted_on.find(mob->GetID()); auto it = casted_on.find(mob->GetID());
if (it != casted_on.end()) { if (it != casted_on.end()) {
@ -414,6 +420,9 @@ void Aura::ProcessOnGroupMembersPets(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
// step 1: check if we're already managing this NPC's buff // step 1: check if we're already managing this NPC's buff
auto it = casted_on.find(mob->GetID()); auto it = casted_on.find(mob->GetID());
if (it != casted_on.end()) { if (it != casted_on.end()) {
@ -572,6 +581,10 @@ void Aura::ProcessTotem(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) { if (mob == this) {
continue; continue;
} }
@ -624,6 +637,10 @@ void Aura::ProcessEnterTrap(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) { if (mob == this) {
continue; continue;
} }
@ -642,6 +659,10 @@ void Aura::ProcessExitTrap(Mob *owner)
for (auto &e : mob_list) { for (auto &e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) { if (mob == this) {
continue; continue;
} }
@ -669,6 +690,10 @@ void Aura::ProcessSpawns()
{ {
const auto &clients = entity_list.GetCloseMobList(this, distance); const auto &clients = entity_list.GetCloseMobList(this, distance);
for (auto &e : clients) { for (auto &e : clients) {
if (!e.second) {
continue;
}
if (!e.second->IsClient()) { if (!e.second->IsClient()) {
continue; continue;
} }

View File

@ -914,6 +914,9 @@ void EntityList::AETaunt(Client *taunter, float range, int32 bonus_hate)
for (auto &it : entity_list.GetCloseMobList(taunter, range)) { for (auto &it : entity_list.GetCloseMobList(taunter, range)) {
Mob *them = it.second; Mob *them = it.second;
if (!them) {
continue;
}
if (!them->IsNPC()) { if (!them->IsNPC()) {
continue; continue;
@ -999,7 +1002,6 @@ void EntityList::AESpell(
for (auto &it : entity_list.GetCloseMobList(caster_mob, distance)) { for (auto &it : entity_list.GetCloseMobList(caster_mob, distance)) {
current_mob = it.second; current_mob = it.second;
if (!current_mob) { if (!current_mob) {
continue; continue;
} }
@ -1150,6 +1152,9 @@ void EntityList::MassGroupBuff(
for (auto &it : entity_list.GetCloseMobList(caster, distance)) { for (auto &it : entity_list.GetCloseMobList(caster, distance)) {
current_mob = it.second; current_mob = it.second;
if (!current_mob) {
continue;
}
/** /**
* Skip center * Skip center
@ -1216,6 +1221,9 @@ void EntityList::AEAttack(
for (auto &it : entity_list.GetCloseMobList(attacker, distance)) { for (auto &it : entity_list.GetCloseMobList(attacker, distance)) {
current_mob = it.second; current_mob = it.second;
if (!current_mob) {
continue;
}
if (current_mob->IsNPC() if (current_mob->IsNPC()
&& current_mob != attacker //this is not needed unless NPCs can use this && current_mob != attacker //this is not needed unless NPCs can use this

View File

@ -1724,6 +1724,9 @@ void EntityList::QueueCloseClients(
for (auto &e : GetCloseMobList(sender, distance)) { for (auto &e : GetCloseMobList(sender, distance)) {
Mob *mob = e.second; Mob *mob = e.second;
if (!mob) {
continue;
}
if (!mob->IsClient()) { if (!mob->IsClient()) {
continue; continue;
@ -4416,6 +4419,9 @@ void EntityList::QuestJournalledSayClose(
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) { if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
for (auto &e : GetCloseMobList(sender, (dist * dist))) { for (auto &e : GetCloseMobList(sender, (dist * dist))) {
Mob *mob = e.second; Mob *mob = e.second;
if (!mob) {
continue;
}
if (!mob->IsClient()) { if (!mob->IsClient()) {
continue; continue;
@ -5551,7 +5557,6 @@ std::vector<Mob*> EntityList::GetTargetsForVirusEffect(Mob *spreader, Mob *origi
bool is_detrimental_spell = IsDetrimentalSpell(spell_id); bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
for (auto &it : entity_list.GetCloseMobList(spreader, range)) { for (auto &it : entity_list.GetCloseMobList(spreader, range)) {
Mob *mob = it.second; Mob *mob = it.second;
if (!mob) { if (!mob) {
continue; continue;
} }

View File

@ -3866,6 +3866,9 @@ void Mob::Say(const char *format, ...)
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) { if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
for (auto &e : entity_list.GetCloseMobList(talker, (distance * distance))) { for (auto &e : entity_list.GetCloseMobList(talker, (distance * distance))) {
Mob *mob = e.second; Mob *mob = e.second;
if (!mob) {
continue;
}
if (!mob->IsClient()) { if (!mob->IsClient()) {
continue; continue;

View File

@ -3463,6 +3463,9 @@ bool NPC::AICheckCloseBeneficialSpells(
*/ */
for (auto & close_mob : entity_list.GetCloseMobList(caster, cast_range)) { for (auto & close_mob : entity_list.GetCloseMobList(caster, cast_range)) {
Mob *mob = close_mob.second; Mob *mob = close_mob.second;
if (!mob) {
continue;
}
if (mob->IsClient()) { if (mob->IsClient()) {
continue; continue;
@ -3539,6 +3542,10 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker)
for (auto &close_mob : entity_list.GetCloseMobList(sender)) { for (auto &close_mob : entity_list.GetCloseMobList(sender)) {
Mob *mob = close_mob.second; Mob *mob = close_mob.second;
if (!mob) {
continue;
}
float distance = DistanceSquared(m_Position, mob->GetPosition()); float distance = DistanceSquared(m_Position, mob->GetPosition());
if (mob->IsClient()) { if (mob->IsClient()) {

View File

@ -2284,6 +2284,9 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, in
auto& mob_list = entity_list.GetCloseMobList(spell_target); auto& mob_list = entity_list.GetCloseMobList(spell_target);
for (auto& e : mob_list) { for (auto& e : mob_list) {
auto mob = e.second; auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) { if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(spell_target->GetPosition(), mob->GetPosition()); float distance = Distance(spell_target->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(spell_target) || mob->CheckLosFN(this)) && distance <= 70) { if ((mob->CheckLosFN(spell_target) || mob->CheckLosFN(this)) && distance <= 70) {