mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Core - Fix RTSC SeeSpellAction crash on malformed WorldPacket (#1841)
## Summary This PR fixes the Crash 1 Source from Issue [#1840](https://github.com/mod-playerbots/mod-playerbots/issues/1840) posted in a @Regrad posted logs, in `SeeSpellAction::Execute` when an RTSC "see spell" event arrives with an empty or malformed `WorldPacket`. In that case the code used to read from the packet without any validation, causing a `ByteBufferException` and a crash in the map thread. ## Fix - Reset the packet read position and check that the RTSC header (castCount + spellId + castFlags) fits into the packet before reading. - Wrap `SpellCastTargets::Read` in a `try { } catch (ByteBufferException const&) { }` block so truncated RTSC payloads are handled gracefully. - Check that `targets.GetDst()` is not `nullptr` before accessing its position. For valid RTSC packets the behavior is unchanged; malformed packets are now safely ignored instead of crashing the server. ## Testing - Sent bots to multiple locations using RTSC and verified they still move as before. - Reproduced the previous crash scenario with malformed RTSC packets: the worldserver no longer crashes and the event is simply ignored. --------- Co-authored-by: bash <hermensb@gmail.com> Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "RTSCValues.h"
|
||||
#include "RtscAction.h"
|
||||
#include "PositionValue.h"
|
||||
#include "ByteBuffer.h"
|
||||
|
||||
Creature* SeeSpellAction::CreateWps(Player* wpOwner, float x, float y, float z, float o, uint32 entry, Creature* lastWp,
|
||||
bool important)
|
||||
@@ -31,27 +32,52 @@ Creature* SeeSpellAction::CreateWps(Player* wpOwner, float x, float y, float z,
|
||||
|
||||
bool SeeSpellAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket p(event.getPacket()); //
|
||||
// RTSC packet data
|
||||
WorldPacket p(event.getPacket());
|
||||
uint8 castCount;
|
||||
uint32 spellId;
|
||||
uint8 castCount, castFlags;
|
||||
uint8 castFlags;
|
||||
|
||||
// check RTSC header size = castCount (uint8) + spellId (uint32) + castFlags (uint8)
|
||||
uint32 const rtscHeaderSize = sizeof(uint8) + sizeof(uint32) + sizeof(uint8);
|
||||
if (p.size() < rtscHeaderSize)
|
||||
{
|
||||
LOG_WARN("playerbots", "SeeSpellAction: Corrupt RTSC packet size={}, expected>={}", p.size(), rtscHeaderSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player* master = botAI->GetMaster();
|
||||
|
||||
p.rpos(0);
|
||||
p >> castCount >> spellId >> castFlags;
|
||||
|
||||
if (!master)
|
||||
return false;
|
||||
|
||||
// read RTSC packet data
|
||||
p.rpos(0); // set read position to start
|
||||
p >> castCount >> spellId >> castFlags;
|
||||
|
||||
// if (!botAI->HasStrategy("RTSC", botAI->GetState()))
|
||||
// return false;
|
||||
|
||||
if (spellId != RTSC_MOVE_SPELL)
|
||||
return false;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
|
||||
// should not throw exception,just defensive measure to prevent any crashes when core function breaks.
|
||||
SpellCastTargets targets;
|
||||
targets.Read(p, botAI->GetMaster());
|
||||
try
|
||||
{
|
||||
targets.Read(p, master);
|
||||
if (!targets.GetDst())
|
||||
{
|
||||
// do not dereference a null destination; ignore malformed RTSC packets instead of crashing
|
||||
LOG_WARN("playerbots", "SeeSpellAction: (malformed) RTSC payload does not contain full targets data");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (ByteBufferException const&)
|
||||
{
|
||||
// ignore malformed RTSC packets instead of crashing
|
||||
LOG_WARN("playerbots", "SeeSpellAction: Failed deserialization (malformed) RTSC payload");
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPosition spellPosition(master->GetMapId(), targets.GetDst()->_position);
|
||||
SET_AI_VALUE(WorldPosition, "see spell location", spellPosition);
|
||||
|
||||
Reference in New Issue
Block a user