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
+44 -20
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) if (!calendarEvent)
{ {
SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID); 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) if (!calendarEvent)
{ {
SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID); SendCalendarCommandResult(remover, CALENDAR_ERROR_EVENT_INVALID);
return; return _events.end();
} }
SendCalendarEventRemovedAlert(*calendarEvent); SendCalendarEventRemovedAlert(*calendarEvent);
@@ -204,9 +205,20 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover)
trans->Append(stmt); trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans); 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; delete calendarEvent;
return; return _events.end();
} }
void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, ObjectGuid /*remover*/) 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();) for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();)
{ {
CalendarEvent* event = *itr; if (CalendarEvent* event = *itr; event->GetCreatorGUID() == guid)
++itr;
if (event->GetCreatorGUID() == guid)
{ {
RemoveEvent(event, ObjectGuid::Empty); itr = RemoveEvent(event, ObjectGuid::Empty, &itr);
continue; continue;
} }
++itr;
} }
CalendarInviteStore playerInvites = GetPlayerInvites(guid); CalendarInviteStore playerInvites = GetPlayerInvites(guid);
@@ -293,22 +304,33 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
void CalendarMgr::RemovePlayerGuildEventsAndSignups(ObjectGuid guid, uint32 guildId) 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())) if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()))
RemoveEvent((*itr)->GetEventId(), guid); {
itr = RemoveEvent((*itr)->GetEventId(), guid);
continue;
}
++itr;
}
CalendarInviteStore playerInvites = GetPlayerInvites(guid); CalendarInviteStore playerInvites = GetPlayerInvites(guid);
for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) 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) if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId)
RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); 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) for (CalendarEventStore::iterator itr = _events.begin(); itr != _events.end(); ++itr)
if ((*itr)->GetEventId() == eventId) if ((*itr)->GetEventId() == eventId)
{
if (it)
*it = itr;
return *itr; return *itr;
}
return nullptr; return nullptr;
} }
@@ -366,10 +388,12 @@ void CalendarMgr::DeleteOldEvents()
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end();) 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; ++itr;
if (event->GetEventTime() < oldEventsTime)
RemoveEvent(event, ObjectGuid::Empty);
} }
} }
+3 -3
View File
@@ -293,7 +293,7 @@ public:
void LoadFromDB(); void LoadFromDB();
CalendarEvent* GetEvent(uint64 eventId); CalendarEvent* GetEvent(uint64 eventId, CalendarEventStore::iterator* it = nullptr);
CalendarEventStore const& GetEvents() const { return _events; } CalendarEventStore const& GetEvents() const { return _events; }
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false); CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false);
CalendarEventStore GetPlayerEvents(ObjectGuid guid); CalendarEventStore GetPlayerEvents(ObjectGuid guid);
@@ -314,8 +314,8 @@ public:
uint32 GetPlayerNumPending(ObjectGuid guid); uint32 GetPlayerNumPending(ObjectGuid guid);
void AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType); void AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType sendType);
void RemoveEvent(uint64 eventId, ObjectGuid remover); CalendarEventStore::iterator RemoveEvent(uint64 eventId, ObjectGuid remover);
void RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover); CalendarEventStore::iterator RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover, CalendarEventStore::const_iterator* currIt = nullptr);
void UpdateEvent(CalendarEvent* calendarEvent); void UpdateEvent(CalendarEvent* calendarEvent);
void AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite, CharacterDatabaseTransaction trans = nullptr); void AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite, CharacterDatabaseTransaction trans = nullptr);