From f97d336d8280082dbc201a203c208051fe0672e8 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 19 Jan 2023 17:30:41 +0100 Subject: [PATCH] Core/Auras: Fixed possible iterator invalidation crashes caused by calling UpdateTargetMap inside loops iterating m_appliedAuras --- src/server/game/Entities/Unit/Unit.cpp | 8 ++++++-- src/server/game/Spells/SpellInfo.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 516f345750..e92caee238 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3870,7 +3870,8 @@ void Unit::RemoveMovementImpairingAuras(bool withRoot) void Unit::RemoveAurasWithMechanic(uint32 mechanicMaskToRemove, AuraRemoveFlags removeMode, uint32 exceptSpellId, bool withEffectMechanics) { - RemoveAppliedAuras([=](AuraApplication const* aurApp) + std::vector aurasToUpdateTargets; + RemoveAppliedAuras([=, &aurasToUpdateTargets](AuraApplication const* aurApp) { Aura* aura = aurApp->GetBase(); if (exceptSpellId && aura->GetId() == exceptSpellId) @@ -3885,9 +3886,12 @@ void Unit::RemoveAurasWithMechanic(uint32 mechanicMaskToRemove, AuraRemoveFlags return true; // effect mechanic matches required mask for removal - don't remove, only update targets - aura->UpdateTargetMap(aura->GetCaster()); + aurasToUpdateTargets.push_back(aura); return false; }, removeMode); + + for (Aura* aura : aurasToUpdateTargets) + aura->UpdateTargetMap(aura->GetCaster()); } void Unit::RemoveAurasByShapeShift() diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 37702ed6be..f83a6e6267 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3106,15 +3106,19 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app target->RemoveAurasWithMechanic(mechanicImmunity, AuraRemoveFlags::ByDefault, Id); else { - target->RemoveAppliedAuras([mechanicImmunity](AuraApplication const* aurApp) + std::vector aurasToUpdateTargets; + target->RemoveAppliedAuras([mechanicImmunity, &aurasToUpdateTargets](AuraApplication const* aurApp) { Aura* aura = aurApp->GetBase(); if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanicImmunity) - aura->UpdateTargetMap(aura->GetCaster()); + aurasToUpdateTargets.push_back(aura); // only update targets, don't remove anything return false; }); + + for (Aura* aura : aurasToUpdateTargets) + aura->UpdateTargetMap(aura->GetCaster()); } } }