From 5d4f009a87f6fd187ad3a52c302d992d174a39aa Mon Sep 17 00:00:00 2001 From: click Date: Sun, 7 Nov 2010 20:08:52 +0100 Subject: [PATCH] Core/Entities: Fix exploit/crash in inventory-handling (CMSG_OPEN_ITEM) -thanks to leak (Adds a scrutiny-based check to baghandling: don't allow placing items in bags that are not "usable" as regular bags) --HG-- branch : trunk --- src/server/game/Entities/Player/Player.cpp | 7 +++---- .../game/Server/Protocol/Handlers/SpellHandler.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5ba76266c5..aaa3f51e37 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11990,10 +11990,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) if (pItem) { sLog.outDebug("STORAGE: DestroyItem bag = %u, slot = %u, item = %u", bag, slot, pItem->GetEntry()); - - // start from destroy contained items (only equipped bag can have its) - if (pItem->IsBag() && pItem->IsEquipped()) // this also prevent infinity loop if empty bag stored in bag == slot - { + // Also remove all contained items if the item is a bag. + // This if() prevents item saving crashes if the condition for a bag to be empty before being destroyed was bypassed somehow. + if (pItem->IsBag() && !((Bag*)pItem)->IsEmpty()) { for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) DestroyItem(slot, i, update); } diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index 23f4ac9796..43c3415d45 100755 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -221,6 +221,15 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) return; } + // Verify that the bag is an actual bag that can be used "normally" + if(!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE)) + { + pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pItem, NULL); + sLog.outError("Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!", + pUser->GetName(), pUser->GetGUIDLow(), pItem->GetGUIDLow(), proto->ItemId); + return; + } + // locked item uint32 lockId = proto->LockID; if (lockId)