From 2730d51266af40ce07c26d2282c111558ea5e14c Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Sep 2011 16:03:46 -0400 Subject: Fix possible total price overflow when buying items. Fix #3137. Thanks to BroodWyrm for finding out the problem. --- src/server/game/Entities/Player/Player.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9b4b8b8251e..4635c8a1aef 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20521,16 +20521,25 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } } - uint32 price = crItem->IsGoldRequired(pProto) ? pProto->BuyPrice * count : 0; + uint32 price = 0; + if(crItem->IsGoldRequired(pProto)) + { + uint32 maxCount = 0xFFFFFFFF / pProto->BuyPrice; //why price is int32? can be negative? + if((uint32)count > maxCount) + { + sLog->outError("Player %s tried to buy %u item id %u, causing overflow", GetName(), (uint32)count, pProto->ItemId); + count = (uint8)maxCount; + } + price = pProto->BuyPrice * count; //it should not exceed 0xFFFFFFFF - // reputation discount - if (price) + // reputation discount price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); - if (!HasEnoughMoney(price)) - { - SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); - return false; + if (!HasEnoughMoney(price)) + { + SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); + return false; + } } if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot)) -- cgit v1.2.3 From 7f4be7e93a03c2f4c964590efb166c7dadcb6837 Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 3 Oct 2011 08:43:21 -0400 Subject: Fix a crash caused by items with 0 price. --- src/server/game/Entities/Player/Player.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4635c8a1aef..0d049a71a77 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20522,15 +20522,15 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } uint32 price = 0; - if(crItem->IsGoldRequired(pProto)) + if(crItem->IsGoldRequired(pProto) && pProto->BuyPrice > 0) //Assume price cannot be negative (do not know why it is int32) { - uint32 maxCount = 0xFFFFFFFF / pProto->BuyPrice; //why price is int32? can be negative? + uint32 maxCount = MAX_MONEY_AMOUNT / pProto->BuyPrice; if((uint32)count > maxCount) { sLog->outError("Player %s tried to buy %u item id %u, causing overflow", GetName(), (uint32)count, pProto->ItemId); count = (uint8)maxCount; } - price = pProto->BuyPrice * count; //it should not exceed 0xFFFFFFFF + price = pProto->BuyPrice * count; //it should not exceed MAX_MONEY_AMOUNT // reputation discount price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); -- cgit v1.2.3