diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-03-06 12:05:54 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-03-06 12:05:54 +0100 |
commit | 1f73cf9f19679f5b888f9df475b94c9405f2d746 (patch) | |
tree | 32c5b406eb0f7214f13a2c12837d7057b95da16d | |
parent | ecf302ac4901281b29ca7c08af80b6c2ca3ad202 (diff) |
Core/AuctionHouse: Fixed possible use after free when auctions are removed with offline buyers
-rw-r--r-- | src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 15 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Handlers/AuctionHouseHandler.cpp | 2 |
3 files changed, 19 insertions, 11 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 639fd280074..a89cca92af9 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -1130,20 +1130,25 @@ void AuctionHouseObject::Update() { SendAuctionExpired(auction, trans); sScriptMgr->OnAuctionExpire(this, auction); + + RemoveAuction(trans, auction, &it); } ///- Or perform the transaction else { + // Copy data before freeing AuctionPosting in auctionHouse->RemoveAuction + // Because auctionHouse->SendAuctionWon can unload items if bidder is offline + // we need to RemoveAuction before sending mails + AuctionPosting copy = *auction; + RemoveAuction(trans, auction, &it); + //we should send an "item sold" message if the seller is online //we send the item to the winner //we send the money to the seller - SendAuctionWon(auction, nullptr, trans); - SendAuctionSold(auction, nullptr, trans); + SendAuctionSold(©, nullptr, trans); + SendAuctionWon(©, nullptr, trans); sScriptMgr->OnAuctionSuccessful(this, auction); } - - ///- In any case clear the auction - RemoveAuction(trans, auction, &it); } // Run DB changes diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp index 0508951226f..95e98c53a6f 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -412,13 +412,16 @@ void AuctionBotBuyer::BuyEntry(AuctionPosting* auction, AuctionHouseObject* auct auction->Bidder = newBidder; auction->BidAmount = auction->BuyoutOrUnitPrice; - // Mails must be under transaction control too to prevent data loss - auctionHouse->SendAuctionWon(auction, nullptr, trans); - auctionHouse->SendAuctionSold(auction, nullptr, trans); - - // Remove auction + // Copy data before freeing AuctionPosting in auctionHouse->RemoveAuction + // Because auctionHouse->SendAuctionWon can unload items if bidder is offline + // we need to RemoveAuction before sending mails + AuctionPosting copy = *auction; auctionHouse->RemoveAuction(trans, auction); + // Mails must be under transaction control too to prevent data loss + auctionHouse->SendAuctionSold(©, nullptr, trans); + auctionHouse->SendAuctionWon(©, nullptr, trans); + // Run SQLs CharacterDatabase.CommitTransaction(trans); } diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 2082b67d451..666a1e00150 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -438,8 +438,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPackets::AuctionHouse::AuctionPlac if (canBuyout && placeBid.BidAmount == auction->BuyoutOrUnitPrice) { // buyout - auctionHouse->SendAuctionWon(auction, player, trans); auctionHouse->SendAuctionSold(auction, nullptr, trans); + auctionHouse->SendAuctionWon(auction, player, trans); auctionHouse->RemoveAuction(trans, auction); } |