diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-01-15 13:30:17 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-01-15 13:30:17 +0100 |
commit | badb55bfd97c16fecfb8cd73ba99e39ecb6b622d (patch) | |
tree | 63c169c36a9db899cb7c9a58d0235ee518112d9b /src/server/game/Spells/SpellMgr.cpp | |
parent | 7587cff0dcb319f92cba4e3f2c1227b1b1276b64 (diff) |
Core/Spells: Added additional validation to loading spell_linked_spell to prevent infinite loops
Closes #28753
Diffstat (limited to 'src/server/game/Spells/SpellMgr.cpp')
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 3ead1a0196a..0b837a966f1 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -625,9 +625,9 @@ bool SpellMgr::IsArenaAllowedEnchancment(uint32 ench_id) const return false; } -std::vector<int32> const* SpellMgr::GetSpellLinked(int32 spell_id) const +std::vector<int32> const* SpellMgr::GetSpellLinked(SpellLinkedType type, uint32 spell_id) const { - return Trinity::Containers::MapGetValuePtr(mSpellLinkedMap, spell_id); + return Trinity::Containers::MapGetValuePtr(mSpellLinkedMap, { type, spell_id }); } PetLevelupSpellSet const* SpellMgr::GetPetLevelupSpellList(uint32 petFamily) const @@ -2047,7 +2047,7 @@ void SpellMgr::LoadSpellLinked() int32 trigger = fields[0].GetInt32(); int32 effect = fields[1].GetInt32(); - int32 type = fields[2].GetUInt8(); + SpellLinkedType type = SpellLinkedType(fields[2].GetUInt8()); SpellInfo const* spellInfo = GetSpellInfo(abs(trigger), DIFFICULTY_NONE); if (!spellInfo) @@ -2057,11 +2057,13 @@ void SpellMgr::LoadSpellLinked() } if (effect >= 0) + { for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { if (spellEffectInfo.CalcValue() == abs(effect)) TC_LOG_ERROR("sql.sql", "The spell {} Effect: {} listed in `spell_linked_spell` has same bp{} like effect (possible hack).", abs(trigger), abs(effect), uint32(spellEffectInfo.EffectIndex)); } + } spellInfo = GetSpellInfo(abs(effect), DIFFICULTY_NONE); if (!spellInfo) @@ -2070,14 +2072,31 @@ void SpellMgr::LoadSpellLinked() continue; } - if (type) //we will find a better way when more types are needed + if (type < SPELL_LINK_CAST || type > SPELL_LINK_REMOVE) { - if (trigger > 0) - trigger += SPELL_LINKED_MAX_SPELLS * type; - else - trigger -= SPELL_LINKED_MAX_SPELLS * type; + TC_LOG_ERROR("sql.sql", "The spell trigger {}, effect {} listed in `spell_linked_spell` has invalid link type {}, skipped.", trigger, effect, type); + continue; + } + + if (trigger < 0) + { + if (type != SPELL_LINK_CAST) + TC_LOG_ERROR("sql.sql", "The spell trigger {} listed in `spell_linked_spell` has invalid link type {}, changed to 0.", trigger, type); + + trigger = -trigger; + type = SPELL_LINK_REMOVE; } - mSpellLinkedMap[trigger].push_back(effect); + + if (type != SPELL_LINK_AURA) + { + if (trigger == effect) + { + TC_LOG_ERROR("sql.sql", "The spell trigger {}, effect {} listed in `spell_linked_spell` triggers itself (infinite loop), skipped.", trigger, effect); + continue; + } + } + + mSpellLinkedMap[{ type, trigger }].push_back(effect); ++count; } while (result->NextRow()); |