From f1a2b8304e4c14c8eebb6d6f36d04ca8b48f5246 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 13 Apr 2026 06:57:44 -0300 Subject: [PATCH] fix(Core/Trade): fix crash from use-after-free in trade logging (#25452) Co-authored-by: Claude Opus 4.6 --- src/server/game/Handlers/TradeHandler.cpp | 32 +++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 37c5bfbae..8fbe3018e 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -458,6 +458,16 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) return; } + // log traded items before moving (pointers become invalid after moveItems) + std::string myItemsStr, hisItemsStr; + for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) + { + if (myItems[i]) + myItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", myItems[i]->GetTemplate()->Name1, myItems[i]->GetEntry(), myItems[i]->GetCount()); + if (hisItems[i]) + hisItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", hisItems[i]->GetTemplate()->Name1, hisItems[i]->GetEntry(), hisItems[i]->GetCount()); + } + // execute trade: 1. remove for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { @@ -495,23 +505,11 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) trader->ModifyMoney(my_trade->GetMoney()); // log completed trade - { - std::string myItemsStr, hisItemsStr = ""; - - for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) - { - if (myItems[i]) - myItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", myItems[i]->GetTemplate()->Name1, myItems[i]->GetEntry(), myItems[i]->GetCount()); - if (hisItems[i]) - hisItemsStr += Acore::StringFormat("{} (Entry:{}) x{}, ", hisItems[i]->GetTemplate()->Name1, hisItems[i]->GetEntry(), hisItems[i]->GetCount()); - } - - LOG_INFO("entities.player.trade", "Trade: Account: {} (IP: {}), Player [{}] ({}) traded with Player [{}] ({}): gave {} copper, received {} copper, gave item(s) [{}], received item(s) [{}]", - GetAccountId(), GetRemoteAddress(), _player->GetName(), _player->GetGUID().GetCounter(), - trader->GetName(), trader->GetGUID().GetCounter(), - my_trade->GetMoney(), his_trade->GetMoney(), - myItemsStr, hisItemsStr); - } + LOG_INFO("entities.player.trade", "Trade: Account: {} (IP: {}), Player [{}] ({}) traded with Player [{}] ({}): gave {} copper, received {} copper, gave item(s) [{}], received item(s) [{}]", + GetAccountId(), GetRemoteAddress(), _player->GetName(), _player->GetGUID().GetCounter(), + trader->GetName(), trader->GetGUID().GetCounter(), + my_trade->GetMoney(), his_trade->GetMoney(), + myItemsStr, hisItemsStr); if (my_spell) my_spell->prepare(&my_targets);