[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)
* (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])].
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();
// 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);
for (auto& e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition());
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);
for (auto& e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->GetPosition(), mob->GetPosition());
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) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) {
auto it = casted_on.find(mob->GetID());
@ -187,6 +190,9 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner)
for (auto &e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
// step 1: check if we're already managing this NPC's buff
auto it = casted_on.find(mob->GetID());
if (it != casted_on.end()) {
@ -414,6 +420,9 @@ void Aura::ProcessOnGroupMembersPets(Mob *owner)
for (auto &e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
// step 1: check if we're already managing this NPC's buff
auto it = casted_on.find(mob->GetID());
if (it != casted_on.end()) {
@ -572,6 +581,10 @@ void Aura::ProcessTotem(Mob *owner)
for (auto &e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) {
continue;
}
@ -624,6 +637,10 @@ void Aura::ProcessEnterTrap(Mob *owner)
for (auto &e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) {
continue;
}
@ -642,6 +659,10 @@ void Aura::ProcessExitTrap(Mob *owner)
for (auto &e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob == this) {
continue;
}
@ -669,6 +690,10 @@ void Aura::ProcessSpawns()
{
const auto &clients = entity_list.GetCloseMobList(this, distance);
for (auto &e : clients) {
if (!e.second) {
continue;
}
if (!e.second->IsClient()) {
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)) {
Mob *them = it.second;
if (!them) {
continue;
}
if (!them->IsNPC()) {
continue;
@ -999,7 +1002,6 @@ void EntityList::AESpell(
for (auto &it : entity_list.GetCloseMobList(caster_mob, distance)) {
current_mob = it.second;
if (!current_mob) {
continue;
}
@ -1150,6 +1152,9 @@ void EntityList::MassGroupBuff(
for (auto &it : entity_list.GetCloseMobList(caster, distance)) {
current_mob = it.second;
if (!current_mob) {
continue;
}
/**
* Skip center
@ -1216,6 +1221,9 @@ void EntityList::AEAttack(
for (auto &it : entity_list.GetCloseMobList(attacker, distance)) {
current_mob = it.second;
if (!current_mob) {
continue;
}
if (current_mob->IsNPC()
&& 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)) {
Mob *mob = e.second;
if (!mob) {
continue;
}
if (!mob->IsClient()) {
continue;
@ -4416,6 +4419,9 @@ void EntityList::QuestJournalledSayClose(
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
for (auto &e : GetCloseMobList(sender, (dist * dist))) {
Mob *mob = e.second;
if (!mob) {
continue;
}
if (!mob->IsClient()) {
continue;
@ -5551,7 +5557,6 @@ std::vector<Mob*> EntityList::GetTargetsForVirusEffect(Mob *spreader, Mob *origi
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
for (auto &it : entity_list.GetCloseMobList(spreader, range)) {
Mob *mob = it.second;
if (!mob) {
continue;
}

View File

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

View File

@ -3463,6 +3463,9 @@ bool NPC::AICheckCloseBeneficialSpells(
*/
for (auto & close_mob : entity_list.GetCloseMobList(caster, cast_range)) {
Mob *mob = close_mob.second;
if (!mob) {
continue;
}
if (mob->IsClient()) {
continue;
@ -3539,6 +3542,10 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker)
for (auto &close_mob : entity_list.GetCloseMobList(sender)) {
Mob *mob = close_mob.second;
if (!mob) {
continue;
}
float distance = DistanceSquared(m_Position, mob->GetPosition());
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);
for (auto& e : mob_list) {
auto mob = e.second;
if (!mob) {
continue;
}
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(spell_target->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(spell_target) || mob->CheckLosFN(this)) && distance <= 70) {