Core/Vehicles: Fixed accessing freed memory in Vehicle::RemoveAllPassengers - _pendingJoinEvents needs to be cleaned from events that had already executed or were aborted

This commit is contained in:
Shauren
2013-02-22 17:46:29 +01:00
parent 0ef974a9de
commit 2f0bbe67ae
2 changed files with 28 additions and 1 deletions

View File

@@ -256,7 +256,7 @@ void Vehicle::RemoveAllPassengers()
/// Setting to_Abort to true will cause @VehicleJoinEvent::Abort to be executed on next @Unit::UpdateEvents call
/// This will properly "reset" the pending join process for the passenger.
while (_pendingJoinEvents.size())
while (!_pendingJoinEvents.empty())
{
VehicleJoinEvent* e = _pendingJoinEvents.front();
e->to_Abort = true;
@@ -705,6 +705,31 @@ void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
_pendingJoinEvents.pop_back();
}
/**
* @fn void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
*
* @brief Removes @VehicleJoinEvent objects from pending join event store.
* This method only removes it after it's executed or aborted to prevent leaving
* pointers to deleted events.
*
* @author Shauren
* @date 22-2-2013
*
* @param [in] e The VehicleJoinEvent* to remove from pending event store.
*/
void Vehicle::RemovePendingEvent(VehicleJoinEvent* e)
{
for (std::deque<VehicleJoinEvent*>::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr)
{
if (*itr == e)
{
_pendingJoinEvents.erase(itr);
break;
}
}
}
/**
* @fn bool VehicleJoinEvent::Execute(uint64, uint32)
*

View File

@@ -101,6 +101,7 @@ class Vehicle : public TransportBase
Position m_lastShootPos;
std::deque<VehicleJoinEvent*> _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
void CancelJoinEvent(VehicleJoinEvent* e);
void RemovePendingEvent(VehicleJoinEvent* e);
};
class VehicleJoinEvent : public BasicEvent
@@ -108,6 +109,7 @@ class VehicleJoinEvent : public BasicEvent
friend class Vehicle;
protected:
VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {}
~VehicleJoinEvent() { Target->RemovePendingEvent(this); }
bool Execute(uint64, uint32);
void Abort(uint64);