fix(Core/Scripts): Fix heap-use-after-free in Fingers of Frost proc handler (#21943)

This commit is contained in:
Anton Popovichenko
2025-04-17 09:27:49 +02:00
committed by GitHub
parent f24e54d037
commit c66972b900
+22 -14
View File
@@ -979,37 +979,40 @@ class spell_mage_fingers_of_frost_proc_aura : public AuraScript
{ {
_chance = 100.f; _chance = 100.f;
_spell = eventInfo.GetProcSpell(); _spell = eventInfo.GetProcSpell();
_procSpellDelayMoment = std::nullopt;
if (!_spell || _spell->GetDelayMoment() <= 0) if (!_spell || _spell->GetDelayMoment() <= 0)
{
PreventDefaultAction(); PreventDefaultAction();
}
if (_spell)
_procSpellDelayMoment = _spell->GetDelayMoment();
} }
else else
{ {
if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH || ((_spell && _spell->GetDelayMoment() > 0) || !eventInfo.GetDamageInfo())) if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH || (_procSpellDelayMoment.value_or(0) > 0 || !eventInfo.GetDamageInfo()))
{
PreventDefaultAction(); PreventDefaultAction();
}
_chance = 0.f; ResetProcState();
_spell = nullptr;
} }
} }
void HandleAfterEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) void HandleAfterEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{ {
if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_HIT) switch (eventInfo.GetSpellPhaseMask())
{ {
_chance = 100.f; case PROC_SPELL_PHASE_HIT: _chance = 100.f; break;
} case PROC_SPELL_PHASE_FINISH: ResetProcState(); break;
else if (eventInfo.GetSpellPhaseMask() == PROC_SPELL_PHASE_FINISH) default: break;
{
_chance = 0.f;
_spell = nullptr;
} }
} }
void ResetProcState()
{
_chance = 0.f;
_spell = nullptr;
_procSpellDelayMoment = std::nullopt;
}
void Register() void Register()
{ {
DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc_aura::CheckProc); DoCheckProc += AuraCheckProcFn(spell_mage_fingers_of_frost_proc_aura::CheckProc);
@@ -1019,10 +1022,15 @@ class spell_mage_fingers_of_frost_proc_aura : public AuraScript
} }
public: public:
// May point to a deleted object.
// Dereferencing is unsafe unless validity is guaranteed by the caller.
Spell const* GetProcSpell() const { return _spell; } Spell const* GetProcSpell() const { return _spell; }
private: private:
float _chance = 0.f; float _chance = 0.f;
std::optional<uint64> _procSpellDelayMoment = std::nullopt;
// May be dangling; points to memory that might no longer be valid.
Spell const* _spell = nullptr; Spell const* _spell = nullptr;
}; };