From 2633a490ebeb9a3191ef88f405c73a21de628183 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 28 Mar 2026 12:02:08 -0700 Subject: [PATCH] fix: remove reinterpret_cast UB in trade slot delegation The TradeSlot structs differ between GameHandler (has bag/slot fields) and InventoryHandler (no bag/slot). The reinterpret_cast was undefined behavior that corrupted memory, potentially causing the teleport bug. Now properly copies fields between the two struct layouts. NOTE: 113 stale getters remain in GameHandler that read duplicate member variables never updated by domain handlers. These need systematic fixing. --- src/game/game_handler.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index b4342e4b..a1240acf 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -5090,11 +5090,32 @@ const std::string& GameHandler::getTradePeerName() const { return tradePeerName_; } const std::array& GameHandler::getMyTradeSlots() const { - if (inventoryHandler_) return reinterpret_cast&>(inventoryHandler_->getMyTradeSlots()); + if (inventoryHandler_) { + // Convert InventoryHandler::TradeSlot → GameHandler::TradeSlot (different struct layouts) + static std::array converted{}; + const auto& src = inventoryHandler_->getMyTradeSlots(); + for (size_t i = 0; i < TRADE_SLOT_COUNT; i++) { + converted[i].itemId = src[i].itemId; + converted[i].displayId = src[i].displayId; + converted[i].stackCount = src[i].stackCount; + converted[i].itemGuid = src[i].itemGuid; + } + return converted; + } return myTradeSlots_; } const std::array& GameHandler::getPeerTradeSlots() const { - if (inventoryHandler_) return reinterpret_cast&>(inventoryHandler_->getPeerTradeSlots()); + if (inventoryHandler_) { + static std::array converted{}; + const auto& src = inventoryHandler_->getPeerTradeSlots(); + for (size_t i = 0; i < TRADE_SLOT_COUNT; i++) { + converted[i].itemId = src[i].itemId; + converted[i].displayId = src[i].displayId; + converted[i].stackCount = src[i].stackCount; + converted[i].itemGuid = src[i].itemGuid; + } + return converted; + } return peerTradeSlots_; } uint64_t GameHandler::getMyTradeGold() const {