diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-05-16 00:47:16 +0200 |
---|---|---|
committer | Ovahlord <dreadkiller@gmx.de> | 2025-05-26 20:49:46 +0200 |
commit | 9deca512b4b040507073733bf98fcf04a2bc7569 (patch) | |
tree | bf8940c19db051c153d5116df43ffd63037e9ab8 /src | |
parent | 220db41a76c444a8f9d70e601c43289d4c1c4ddc (diff) |
Core/Conditions: Catch exceptions caused by invalid WorldStateExpression data
(cherry picked from commit 3f036bc722153b459c4792cde2ecda9641c1e7b9)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 3eb7aa126a2..45efdb10353 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -3189,14 +3189,14 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player const* player, PlayerConditio return true; } -ByteBuffer HexToBytes(const std::string& hex) +static ByteBuffer HexToBytes(std::string_view const& hex) { ByteBuffer buffer(hex.length() / 2, ByteBuffer::Resize{}); Trinity::Impl::HexStrToByteArray(hex, buffer.data(), buffer.size()); return buffer; } -static int32(* const WorldStateExpressionFunctions[WSE_FUNCTION_MAX])(Map const*, uint32, uint32) = +static constexpr int32(* const WorldStateExpressionFunctions[WSE_FUNCTION_MAX])(Map const*, uint32, uint32) = { // WSE_FUNCTION_NONE [](Map const* /*map*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32 @@ -3538,21 +3538,24 @@ bool EvalRelOp(ByteBuffer& buffer, Map const* map) return false; } -bool ConditionMgr::IsMeetingWorldStateExpression(Map const* map, WorldStateExpressionEntry const* expression) +bool ConditionMgr::IsMeetingWorldStateExpression(Map const* map, WorldStateExpressionEntry const* expression) try { ByteBuffer buffer = HexToBytes(expression->Expression); if (buffer.empty()) return false; - bool enabled = buffer.read<bool>(); + uint8 enabled = buffer.read<uint8>(); if (!enabled) return false; bool finalResult = EvalRelOp(buffer, map); - WorldStateExpressionLogic resultLogic = buffer.read<WorldStateExpressionLogic>(); - while (resultLogic != WorldStateExpressionLogic::None) + do { + WorldStateExpressionLogic resultLogic = buffer.read<WorldStateExpressionLogic>(); + if (resultLogic == WorldStateExpressionLogic::None) + break; + bool secondResult = EvalRelOp(buffer, map); switch (resultLogic) @@ -3563,15 +3566,15 @@ bool ConditionMgr::IsMeetingWorldStateExpression(Map const* map, WorldStateExpre default: break; } - - if (buffer.rpos() >= buffer.size()) - break; - - resultLogic = buffer.read<WorldStateExpressionLogic>(); - } + } while (buffer.rpos() >= buffer.size()); return finalResult; } +catch (std::exception const& e) +{ + TC_LOG_ERROR("condition", "Failed to parse WorldStateExpression {}: {}", expression->ID, e.what()); + return false; +} int32 GetUnitConditionVariable(Unit const* unit, Unit const* otherUnit, UnitConditionVariable variable, int32 value) { |