mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-10-10 07:06:38 +08:00
fix(Core/Vehicle): avoid Vehicle-kit use-after-free in TeleportVehicle (#26116)
Co-authored-by: sudlud <[email protected]>
This commit is contained in:
@@ -599,12 +599,33 @@ bool Vehicle::IsControllableVehicle() const
|
||||
|
||||
void Vehicle::TeleportVehicle(float x, float y, float z, float ang)
|
||||
{
|
||||
_me->GetMap()->LoadGrid(x, y);
|
||||
_me->NearTeleportTo(x, y, z, ang, true);
|
||||
// Snapshot passenger GUIDs and cache the base BEFORE teleporting.
|
||||
// Teleporting the base (Player::TeleportTo) may drop the mount/vehicle aura
|
||||
// on a long hop (>100 yd) and call ExitVehicle() -> Unit::RemoveVehicleKit()
|
||||
// -> delete m_vehicleKit, freeing THIS Vehicle (and its Seats) mid-call.
|
||||
// Reading Seats after that is a use-after-free (see upstream PR #26116 review).
|
||||
Unit* base = _me;
|
||||
Vehicle* self = this;
|
||||
std::vector<ObjectGuid> passengers;
|
||||
passengers.reserve(Seats.size());
|
||||
for (auto const& seat : Seats)
|
||||
if (!seat.second.IsEmpty())
|
||||
passengers.push_back(seat.second.Passenger.Guid);
|
||||
|
||||
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
|
||||
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger.Guid))
|
||||
base->GetMap()->LoadGrid(x, y);
|
||||
base->NearTeleportTo(x, y, z, ang, true, true); // vehicleTeleport=true: do not dismount base mid-call
|
||||
|
||||
// THIS Vehicle may have been deleted by the base teleport above (kit freed).
|
||||
// If so, bail out - passengers were already ejected by ~Vehicle::Uninstall().
|
||||
if (base->GetVehicleKit() != self)
|
||||
return;
|
||||
|
||||
for (ObjectGuid const& guid : passengers)
|
||||
if (Unit* passenger = ObjectAccessor::GetUnit(*base, guid))
|
||||
{
|
||||
if (!passenger->IsInWorld())
|
||||
continue;
|
||||
|
||||
if (passenger->IsPlayer())
|
||||
{
|
||||
passenger->ToPlayer()->SetMover(passenger);
|
||||
|
||||
Reference in New Issue
Block a user