Fix possible total price overflow when buying items. Fix #3137.

Thanks to BroodWyrm for finding out the problem.
This commit is contained in:
megamage
2011-09-28 16:03:46 -04:00
parent 8dd88fa43c
commit 2730d51266
+16 -7
View File
@@ -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))