aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-08-19 17:07:21 -0500
committermegamage <none@none>2009-08-19 17:07:21 -0500
commitc9117721255b24d86f00b3f94c6f112fefa5bfdd (patch)
tree8daf9665b3142c4974c90e38414ae7669db694cc
parentf5085b2f39c91ed0103c79d95f8d18a4ef2a6371 (diff)
[8389] Implement check really read received packet size and warning it not all data read. Author: VladimirMangos
* This let more easy catch packet structure chnages at client switch. * Fixed structure CMSG_GUILD_BANK_SWAP_ITEMS * Fixed structure CMSG_SPLIT_ITEM, CMSG_SELL_ITEM * Added read data amount fixes for some other packets. Thanks to TOM_RUS in help check correct packets structure. Note: not all packets possible fixed. Please report for not fixed cases at errors: "opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)" --HG-- branch : trunk
-rw-r--r--src/game/CalendarHandler.cpp10
-rw-r--r--src/game/GuildHandler.cpp38
-rw-r--r--src/game/ItemHandler.cpp12
-rw-r--r--src/game/MiscHandler.cpp7
-rw-r--r--src/game/VoiceChatHandler.cpp3
-rw-r--r--src/game/WorldSession.cpp31
-rw-r--r--src/game/WorldSession.h4
-rw-r--r--src/game/WorldSocket.cpp2
-rw-r--r--src/shared/ByteBuffer.h3
9 files changed, 74 insertions, 36 deletions
diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp
index cfc853daa82..93d3b7eae26 100644
--- a/src/game/CalendarHandler.cpp
+++ b/src/game/CalendarHandler.cpp
@@ -97,6 +97,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//std::string unk1, unk2;
//recv_data >> (std::string)unk1;
@@ -132,6 +133,7 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@@ -150,6 +152,7 @@ void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@@ -161,6 +164,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@@ -172,6 +176,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@@ -185,6 +190,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@@ -196,6 +202,7 @@ void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@@ -207,6 +214,7 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@@ -219,6 +227,7 @@ void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@@ -231,6 +240,7 @@ void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
recv_data.hexlike();
+ recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
index 36f8ffbe327..c6ae1fe19c0 100644
--- a/src/game/GuildHandler.cpp
+++ b/src/game/GuildHandler.cpp
@@ -614,12 +614,14 @@ void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if(!guild)
{
+ recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
return;
}
else if(GetPlayer()->GetGUID() != guild->GetLeader())
{
+ recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
return;
}
@@ -1026,10 +1028,14 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
uint64 GoGuid;
uint8 BankToBank;
- uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0;
- uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1;
+ uint8 BankTab, BankTabSlot, AutoStore;
+ uint8 PlayerSlot = NULL_SLOT;
+ uint8 PlayerBag = NULL_BAG;
+ uint8 BankTabDst, BankTabSlotDst, unk2;
+ uint8 ToChar = 1;
uint32 ItemEntry, unk1;
- bool BankToChar = false;
+ uint32 AutoStoreCount = 0;
+ uint32 SplitedAmount = 0;
recv_data >> GoGuid >> BankToBank;
if (BankToBank)
@@ -1043,10 +1049,11 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
recv_data >> unk2; // always 0
recv_data >> SplitedAmount;
- if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS)
- return;
- if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
+ if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS || BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
+ {
+ recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
return;
+ }
}
else
{
@@ -1057,17 +1064,22 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
if (AutoStore)
{
recv_data >> AutoStoreCount;
+ recv_data.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in guild->ToChar)
+ recv_data.read_skip<uint32>(); // unknown, always 0
}
- recv_data >> PlayerBag;
- recv_data >> PlayerSlot;
- if (!AutoStore)
+ else
{
+ recv_data >> PlayerBag;
+ recv_data >> PlayerSlot;
recv_data >> ToChar;
recv_data >> SplitedAmount;
}
if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
+ {
+ recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
return;
+ }
}
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
@@ -1202,14 +1214,6 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
// Player <-> Bank
- // char->bank autostore click return BankTabSlot = 255 = NULL_SLOT
- // do similar for bank->char
- if(AutoStore && ToChar)
- {
- PlayerBag = NULL_BAG;
- PlayerSlot = NULL_SLOT;
- }
-
// allow work with inventory only
if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
{
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 602e007c7f3..e79f16acfc8 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -32,7 +32,8 @@
void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
{
//sLog.outDebug("WORLD: CMSG_SPLIT_ITEM");
- uint8 srcbag, srcslot, dstbag, dstslot, count;
+ uint8 srcbag, srcslot, dstbag, dstslot;
+ uint32 count;
recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count;
//sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count);
@@ -490,12 +491,9 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
{
sLog.outDebug( "WORLD: Received CMSG_SELL_ITEM" );
uint64 vendorguid, itemguid;
- uint8 _count;
+ uint32 count;
- recv_data >> vendorguid >> itemguid >> _count;
-
- // prevent possible overflow, as Trinity uses uint32 for item count
- uint32 count = _count;
+ recv_data >> vendorguid >> itemguid >> count;
if(!itemguid)
return;
@@ -971,6 +969,8 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data)
{
uint32 itemid;
recv_data >> itemid;
+ recv_data.read_skip<uint64>(); // guid
+
sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid);
ItemPrototype const *pProto = objmgr.GetItemPrototype( itemid );
if( pProto )
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index f0f0a4b42a4..fc7dd114af2 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -931,6 +931,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
if(decompressedSize > 0xFFFF)
{
+ recv_data.rpos(recv_data.wpos()); // unnneded warning spam in this case
sLog.outError("UAD: Account data packet too big, size %u", decompressedSize);
return;
}
@@ -941,10 +942,13 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
uLongf realSize = decompressedSize;
if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK)
{
+ recv_data.rpos(recv_data.wpos()); // unnneded warning spam in this case
sLog.outError("UAD: Failed to decompress account data");
return;
}
+ recv_data.rpos(recv_data.wpos()); // uncompress read (recv_data.size() - recv_data.rpos())
+
std::string adata;
dest >> adata;
@@ -1050,7 +1054,8 @@ void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & recv_data )
/* WorldSession::Update( getMSTime() );*/
DEBUG_LOG( "WORLD: Time Lag/Synchronization Resent/Update" );
- recv_data.read_skip2<uint64,uint32>();
+ recv_data.read_skip<uint64>();
+ recv_data.read_skip<uint32>();
/*
uint64 guid;
uint32 time_skipped;
diff --git a/src/game/VoiceChatHandler.cpp b/src/game/VoiceChatHandler.cpp
index e4c588dc4af..6023233c444 100644
--- a/src/game/VoiceChatHandler.cpp
+++ b/src/game/VoiceChatHandler.cpp
@@ -28,7 +28,8 @@ void WorldSession::HandleVoiceSessionEnableOpcode( WorldPacket & recv_data )
{
sLog.outDebug("WORLD: CMSG_VOICE_SESSION_ENABLE");
// uint8 isVoiceEnabled, uint8 isMicrophoneEnabled
- recv_data.read_skip2<uint8,uint8>();
+ recv_data.read_skip<uint8>();
+ recv_data.read_skip<uint8>();
recv_data.hexlike();
}
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 6b4653c4263..824ba785e48 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -147,7 +147,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
}
/// Logging helper for unexpected opcodes
-void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
+void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason)
{
sLog.outError( "SESSION: received unexpected opcode %s (0x%.4X) %s",
LookupOpcodeName(packet->GetOpcode()),
@@ -155,6 +155,15 @@ void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
reason);
}
+/// Logging helper for unexpected opcodes
+void WorldSession::LogUnprocessedTail(WorldPacket *packet)
+{
+ sLog.outError( "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
+ LookupOpcodeName(packet->GetOpcode()),
+ packet->GetOpcode(),
+ packet->rpos(),packet->wpos());
+}
+
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 /*diff*/)
{
@@ -188,30 +197,40 @@ bool WorldSession::Update(uint32 /*diff*/)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
if(!m_playerRecentlyLogout)
- logUnexpectedOpcode(packet, "the player has not logged in yet");
+ LogUnexpectedOpcode(packet, "the player has not logged in yet");
}
else if(_player->IsInWorld())
+ {
(this->*opHandle.handler)(*packet);
+ if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
+ LogUnprocessedTail(packet);
+ }
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
break;
case STATUS_TRANSFER:
if(!_player)
- logUnexpectedOpcode(packet, "the player has not logged in yet");
+ LogUnexpectedOpcode(packet, "the player has not logged in yet");
else if(_player->IsInWorld())
- logUnexpectedOpcode(packet, "the player is still in world");
+ LogUnexpectedOpcode(packet, "the player is still in world");
else
+ {
(this->*opHandle.handler)(*packet);
+ if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
+ LogUnprocessedTail(packet);
+ }
break;
case STATUS_AUTHED:
// prevent cheating with skip queue wait
if(m_inQueue)
{
- logUnexpectedOpcode(packet, "the player not pass queue yet");
+ LogUnexpectedOpcode(packet, "the player not pass queue yet");
break;
}
m_playerRecentlyLogout = false;
(this->*opHandle.handler)(*packet);
+ if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
+ LogUnprocessedTail(packet);
break;
case STATUS_NEVER:
break;
@@ -221,7 +240,7 @@ bool WorldSession::Update(uint32 /*diff*/)
break;
}
}
- catch(ByteBufferException &exception)
+ catch(ByteBufferException &)
{
sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 1a61a23d7bd..948c0f678ee 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -722,7 +722,9 @@ class TRINITY_DLL_SPEC WorldSession
void moveItems(Item* myItems[], Item* hisItems[]);
// logging helper
- void logUnexpectedOpcode(WorldPacket *packet, const char * reason);
+ void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
+ void LogUnprocessedTail(WorldPacket *packet);
+
Player *_player;
WorldSocket *m_Socket;
std::string m_Address;
diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp
index c87f36eece9..0425085ea9f 100644
--- a/src/game/WorldSocket.cpp
+++ b/src/game/WorldSocket.cpp
@@ -655,7 +655,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
}
}
}
- catch(ByteBufferException &exception)
+ catch(ByteBufferException &)
{
sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h
index 89b049990e8..b22dbdee729 100644
--- a/src/shared/ByteBuffer.h
+++ b/src/shared/ByteBuffer.h
@@ -265,9 +265,6 @@ class ByteBuffer
template<typename T>
void read_skip() { read_skip(sizeof(T)); }
- template<typename T1, typename T2>
- void read_skip2() { read_skip(sizeof(T1)+sizeof(T2)); }
-
void read_skip(size_t skip)
{
if(_rpos + skip > size())