fix(Core/Calendar): Fix crash on deletion while iterating through calendar events. (#21667)

This commit is contained in:
Anton Popovichenko
2025-03-14 10:41:04 +01:00
committed by GitHub
parent 82e76e8781
commit e0a2622138
2 changed files with 47 additions and 23 deletions

View File

@@ -154,25 +154,26 @@ void CalendarMgr::AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite
}
}
void CalendarMgr::RemoveEvent(uint64 eventId, ObjectGuid remover)
CalendarEventStore::iterator CalendarMgr::RemoveEvent(uint64 eventId, ObjectGuid remover)
{
CalendarEvent* calendarEvent = GetEvent(eventId);
CalendarEventStore::iterator current;
CalendarEvent* calendarEvent = GetEvent(eventId, &current);
if (!calendarEvent)
{
SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID);
return;
return _events.end();
}
RemoveEvent(calendarEvent, remover);
CalendarEventStore::const_iterator constItr(current);
return RemoveEvent(calendarEvent, remover, &constItr);
}
void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover)
{
CalendarEventStore::iterator CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover, CalendarEventStore::const_iterator* currIt) {
if (!calendarEvent)
{
SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID);
return;
return _events.end();
}
SendCalendarEventRemovedAlert(*calendarEvent);
@@ -204,9 +205,20 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover)
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
_events.erase(calendarEvent);
if (currIt)
{
delete calendarEvent;
return _events.erase(*currIt);
}
if (auto it = _events.find(calendarEvent); it != _events.end())
{
delete calendarEvent;
return _events.erase(it);
}
delete calendarEvent;
return;
return _events.end();
}
void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, ObjectGuid /*remover*/)
@@ -277,13 +289,12 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
{
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
{
CalendarEvent* event = *itr;
++itr;
if (event->GetCreatorGUID() == guid)
if (CalendarEvent* event = *itr; event->GetCreatorGUID() == guid)
{
RemoveEvent(event, ObjectGuid::Empty);
itr = RemoveEvent(event, ObjectGuid::Empty, &itr);
continue;
}
++itr;
}
CalendarInviteStore playerInvites = GetPlayerInvites(guid);
@@ -293,22 +304,33 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
void CalendarMgr::RemovePlayerGuildEventsAndSignups(ObjectGuid guid, uint32 guildId)
{
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
{
if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()))
RemoveEvent((*itr)->GetEventId(), guid);
{
itr = RemoveEvent((*itr)->GetEventId(), guid);
continue;
}
++itr;
}
CalendarInviteStore playerInvites = GetPlayerInvites(guid);
for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr)
if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId()))
if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId(), nullptr))
if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId)
RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid);
}
CalendarEvent* CalendarMgr::GetEvent(uint64 eventId)
CalendarEvent* CalendarMgr::GetEvent(uint64 eventId, CalendarEventStore::iterator* it)
{
for (CalendarEventStore::iterator itr = _events.begin(); itr != _events.end(); ++itr)
if ((*itr)->GetEventId() == eventId)
{
if (it)
*it = itr;
return *itr;
}
return nullptr;
}
@@ -366,10 +388,12 @@ void CalendarMgr::DeleteOldEvents()
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
{
CalendarEvent* event = *itr;
if (CalendarEvent* event = *itr; event->GetEventTime() < oldEventsTime)
{
itr = RemoveEvent(event, ObjectGuid::Empty, &itr);
continue;
}
++itr;
if (event->GetEventTime() < oldEventsTime)
RemoveEvent(event, ObjectGuid::Empty);
}
}

View File

@@ -293,7 +293,7 @@ public:
void LoadFromDB();
CalendarEvent* GetEvent(uint64 eventId);
CalendarEvent* GetEvent(uint64 eventId, CalendarEventStore::iterator* it = nullptr);
CalendarEventStore const& GetEvents() const { return _events; }
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false);
CalendarEventStore GetPlayerEvents(ObjectGuid guid);
@@ -314,8 +314,8 @@ public:
uint32 GetPlayerNumPending(ObjectGuid guid);
void AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType);
void RemoveEvent(uint64 eventId, ObjectGuid remover);
void RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover);
CalendarEventStore::iterator RemoveEvent(uint64 eventId, ObjectGuid remover);
CalendarEventStore::iterator RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover, CalendarEventStore::const_iterator* currIt = nullptr);
void UpdateEvent(CalendarEvent* calendarEvent);
void AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite, CharacterDatabaseTransaction trans = nullptr);