From 2500ea5772386a87c7e5baa45691a959c7b59710 Mon Sep 17 00:00:00 2001 From: r4dish Date: Sat, 8 Jun 2024 20:46:07 +0200 Subject: [PATCH] Core/Spells: Fix sobering spells and possible uint8 overflow/underflow in SPELL_EFFECT_INEBRIATE handler. (cherry picked from commit d9460428c6639ea8dc3f66e0e39cd37cf62a1252) --- src/server/game/Spells/SpellEffects.cpp | 26 ++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 81bfc9fa71..62ed307d00 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3525,15 +3525,27 @@ void Spell::EffectInebriate() return; Player* player = unitTarget->ToPlayer(); + uint8 currentDrunk = player->GetDrunkValue(); + int32 drunkMod = GetEffectValueAsInt(); - uint8 currentDrunkValue = player->GetDrunkValue(); - uint8 drunkValue = std::clamp(GetEffectValueAsInt() + currentDrunkValue, 0, 100); - if (currentDrunkValue == 100 && currentDrunkValue == drunkValue) - if (roll_chance(25.0f)) - player->CastSpell(player, 67468, CastSpellExtraArgs() - .SetTriggeringSpell(this)); // Drunken Vomit + if (drunkMod == 0) + return; - player->SetDrunkValue(drunkValue, m_CastItem ? m_CastItem->GetEntry() : 0); + // drunkMod may contain values that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874) + // In addition, we would not want currentDrunk to become more than 100. + // So before adding the values, let's check that everything is fine. + if (drunkMod > static_cast(100 - currentDrunk)) + currentDrunk = 100; + else if (drunkMod < static_cast(0 - currentDrunk)) + currentDrunk = 0; + else + currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range. + + player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0); + + if (currentDrunk == 100 && drunkMod > 0 && roll_chance(25)) + player->CastSpell(player, 67468, CastSpellExtraArgs() + .SetTriggeringSpell(this)); // Drunken Vomit } void Spell::EffectFeedPet()