From 39f5fe96a08c5a5de95c28297f5561a9d038fd04 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 11 Feb 2022 17:38:53 +0300 Subject: NEN: memory corruption fix --- plugins/NewEventNotify/src/main.cpp | 15 +++--- plugins/NewEventNotify/src/popup.cpp | 97 ++++++++++++++++-------------------- plugins/NewEventNotify/src/stdafx.h | 17 ++++--- 3 files changed, 59 insertions(+), 70 deletions(-) (limited to 'plugins/NewEventNotify/src') diff --git a/plugins/NewEventNotify/src/main.cpp b/plugins/NewEventNotify/src/main.cpp index 0d164e9d7f..8039f7bd4b 100644 --- a/plugins/NewEventNotify/src/main.cpp +++ b/plugins/NewEventNotify/src/main.cpp @@ -83,21 +83,22 @@ int HookedNewEvent(WPARAM hContact, LPARAM hDbEvent) //is it an event sent by the user? -> don't show if (dbe.flags & DBEF_SENT) { // JK, only message event, do not influence others - if (g_plugin.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) { - if (auto *pdata = PU_GetByContact(hContact, EVENTTYPE_MESSAGE)) - PopupAct(pdata->hWnd, MASK_DISMISS, pdata); // JK, only dismiss, i.e. do not kill event (e.g. file transfer) - } + auto *pdata = PU_GetByContact(hContact, EVENTTYPE_MESSAGE); + if (g_plugin.bHideSend && pdata) + PopupAct(pdata->hWnd, MASK_DISMISS, pdata); // JK, only dismiss, i.e. do not kill event (e.g. file transfer) return 0; } + // which status do we have, are we allowed to post popups? // UNDER CONSTRUCTION!!! CallService(MS_CLIST_GETSTATUSMODE, 0, 0); /// TODO: JK: ???? if (dbe.eventType == EVENTTYPE_MESSAGE && (g_plugin.bMsgWindowCheck && hContact && CheckMsgWnd(hContact))) return 0; - //is another popup for this contact already present? -> merge message popups if enabled - if (dbe.eventType == EVENTTYPE_MESSAGE && (g_plugin.bMergePopup && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1)) - PopupUpdate(hContact, hDbEvent); + // is another popup for this contact already present? -> merge message popups if enabled + auto *pdata = PU_GetByContact(hContact, EVENTTYPE_MESSAGE); + if (dbe.eventType == EVENTTYPE_MESSAGE && g_plugin.bMergePopup && pdata) + PopupUpdate(*pdata, hDbEvent); else PopupShow(hContact, hDbEvent, (UINT)dbe.eventType); diff --git a/plugins/NewEventNotify/src/popup.cpp b/plugins/NewEventNotify/src/popup.cpp index f5724dfc44..b991a40c7c 100644 --- a/plugins/NewEventNotify/src/popup.cpp +++ b/plugins/NewEventNotify/src/popup.cpp @@ -26,29 +26,12 @@ extern int g_IsServiceAvail; -static LIST arPopupList(10, NumericKeySortT); +static mir_cs csPopupList; +static OBJLIST arPopupList(10, PtrKeySortT); -PLUGIN_DATA* PU_GetByContact(MCONTACT hContact, UINT eventType) -{ - for (auto &it : arPopupList) - if (it->hContact == hContact && (eventType == -1 || it->eventType == (UINT)eventType)) - return it; - - return nullptr; -} - -int NumberPopupData(MCONTACT hContact, UINT eventType) -{ - for (auto &it : arPopupList) - if (it->hContact == hContact && (eventType == -1 || it->eventType == (UINT)eventType)) - return arPopupList.indexOf(&it); - - return -1; -} - -static void FreePopupEventData(PLUGIN_DATA *pdata) +PLUGIN_DATA::~PLUGIN_DATA() { - EVENT_DATA_EX *eventData = pdata->firstEventData; + EVENT_DATA_EX *eventData = firstEventData; while (eventData) { if (eventData->next) { eventData = eventData->next; @@ -62,6 +45,15 @@ static void FreePopupEventData(PLUGIN_DATA *pdata) } } +PLUGIN_DATA* PU_GetByContact(MCONTACT hContact, UINT eventType) +{ + for (auto &it : arPopupList) + if (it->hContact == hContact && (eventType == -1 || it->eventType == (UINT)eventType)) + return it; + + return nullptr; +} + static void DoDefaultHandling(PLUGIN_DATA *pdata) { if (pdata->hContact == 0) @@ -110,13 +102,11 @@ int PopupAct(HWND hWnd, UINT mask, PLUGIN_DATA *pdata) db_event_markRead(pdata->hContact, eventData->hEvent); eventData = eventData->next; } - FreePopupEventData(pdata); } } if (mask & MASK_DISMISS) { KillTimer(hWnd, TIMER_TO_ACTION); - FreePopupEventData(pdata); PUDeletePopup(hWnd); } @@ -139,7 +129,10 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA PopupAct(hWnd, g_plugin.maskActR, pdata); break; case UM_FREEPLUGINDATA: - mir_free(pdata); + { + mir_cslock lck(csPopupList); + arPopupList.remove(pdata); + } return TRUE; case UM_INITPOPUP: pdata->hWnd = hWnd; @@ -150,12 +143,12 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA if ((short)HIWORD(wParam) > 0 && pdata->firstShowEventData->prev && (g_plugin.bShowON || pdata->firstShowEventData->number >= g_plugin.iNumberMsg)) { pdata->firstShowEventData = pdata->firstShowEventData->prev; - PopupUpdate(pdata->hContact, NULL); + PopupUpdate(*pdata, NULL); } if ((short)HIWORD(wParam) < 0 && pdata->firstShowEventData->next && (!g_plugin.bShowON || pdata->countEvent - pdata->firstShowEventData->number >= g_plugin.iNumberMsg)) { pdata->firstShowEventData = pdata->firstShowEventData->next; - PopupUpdate(pdata->hContact, NULL); + PopupUpdate(*pdata, NULL); } break; case WM_SETCURSOR: @@ -180,7 +173,7 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA ///////////////////////////////////////////////////////////////////////////////////////// -static wchar_t *ShortenPreview(DBEVENTINFO *dbe) +static wchar_t* ShortenPreview(DBEVENTINFO *dbe) { bool fAddEllipsis = false; size_t iPreviewLimit = g_plugin.iLimitPreview; @@ -403,7 +396,7 @@ int PopupShow(MCONTACT hContact, MEVENT hEvent, UINT eventType) hContact = DbGetAuthEventContact(&dbe); // set plugin_data ... will be usable within PopupDlgProc - PLUGIN_DATA *pdata = (PLUGIN_DATA*)mir_calloc(sizeof(PLUGIN_DATA)); + PLUGIN_DATA *pdata = new PLUGIN_DATA(); pdata->eventType = eventType; pdata->hContact = hContact; pdata->countEvent = 1; @@ -425,51 +418,45 @@ int PopupShow(MCONTACT hContact, MEVENT hEvent, UINT eventType) wcsncpy(pudw.lpwzText, ptrW(GetEventPreview(&dbe)), MAX_SECONDLINE); } - arPopupList.insert(pdata); - // send data to popup plugin - if (PUAddPopupW(&pudw) < 0) { - // popup creation failed, release popupdata - FreePopupEventData(pdata); - mir_free(pdata); - } + if (PUAddPopupW(&pudw) < 0) + delete pdata; + mir_cslock lck(csPopupList); + arPopupList.insert(pdata); return 0; } -int PopupUpdate(MCONTACT hContact, MEVENT hEvent) +int PopupUpdate(PLUGIN_DATA &pdata, MEVENT hEvent) { - // merge only message popups - PLUGIN_DATA *pdata = arPopupList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; - if (hEvent) { - pdata->countEvent++; - - pdata->lastEventData->next = (EVENT_DATA_EX *)mir_alloc(sizeof(EVENT_DATA_EX)); - pdata->lastEventData->next->prev = pdata->lastEventData; - pdata->lastEventData = pdata->lastEventData->next; - pdata->lastEventData->hEvent = hEvent; - pdata->lastEventData->number = pdata->lastEventData->prev->number + 1; - pdata->lastEventData->next = nullptr; - if (!g_plugin.bShowON && pdata->countEvent > g_plugin.iNumberMsg && g_plugin.iNumberMsg) - pdata->firstShowEventData = pdata->firstShowEventData->next; + pdata.countEvent++; + + pdata.lastEventData->next = (EVENT_DATA_EX *)mir_alloc(sizeof(EVENT_DATA_EX)); + pdata.lastEventData->next->prev = pdata.lastEventData; + pdata.lastEventData = pdata.lastEventData->next; + pdata.lastEventData->hEvent = hEvent; + pdata.lastEventData->number = pdata.lastEventData->prev->number + 1; + pdata.lastEventData->next = nullptr; + if (!g_plugin.bShowON && pdata.countEvent > g_plugin.iNumberMsg && g_plugin.iNumberMsg) + pdata.firstShowEventData = pdata.firstShowEventData->next; // re-init timer delay - KillTimer(pdata->hWnd, TIMER_TO_ACTION); - SetTimer(pdata->hWnd, TIMER_TO_ACTION, pdata->iSeconds * 1000, nullptr); + KillTimer(pdata.hWnd, TIMER_TO_ACTION); + SetTimer(pdata.hWnd, TIMER_TO_ACTION, pdata.iSeconds * 1000, nullptr); } wchar_t lpzText[MAX_SECONDLINE * 2] = L"\0\0"; if (g_plugin.bShowHeaders) - mir_snwprintf(lpzText, TranslateT("[b]Number of new message(s): %d[/b]\n"), pdata->countEvent); + mir_snwprintf(lpzText, TranslateT("[b]Number of new message(s): %d[/b]\n"), pdata.countEvent); int doReverse = g_plugin.bShowON; - if ((pdata->firstShowEventData != pdata->firstEventData && doReverse) || (pdata->firstShowEventData != pdata->lastEventData && !doReverse)) + if ((pdata.firstShowEventData != pdata.firstEventData && doReverse) || (pdata.firstShowEventData != pdata.lastEventData && !doReverse)) mir_snwprintf(lpzText, L"%s...\n", lpzText); // take the active event as starting one - EVENT_DATA_EX *eventData = pdata->firstShowEventData; + EVENT_DATA_EX *eventData = pdata.firstShowEventData; int iEvent = 0; while (true) { @@ -515,6 +502,6 @@ int PopupUpdate(MCONTACT hContact, MEVENT hEvent) if ((doReverse && eventData->next) || (!doReverse && eventData->prev)) mir_snwprintf(lpzText, L"%s\n...", lpzText); - PUChangeTextW(pdata->hWnd, lpzText); + PUChangeTextW(pdata.hWnd, lpzText); return 0; } diff --git a/plugins/NewEventNotify/src/stdafx.h b/plugins/NewEventNotify/src/stdafx.h index 6c1a0e4527..bcb4362ab8 100644 --- a/plugins/NewEventNotify/src/stdafx.h +++ b/plugins/NewEventNotify/src/stdafx.h @@ -195,18 +195,20 @@ struct EVENT_DATA_EX { MEVENT hEvent; int number; - struct EVENT_DATA_EX* next; - struct EVENT_DATA_EX* prev; + EVENT_DATA_EX *next; + EVENT_DATA_EX *prev; }; -struct PLUGIN_DATA +struct PLUGIN_DATA : public MZeroedObject { + ~PLUGIN_DATA(); + MCONTACT hContact; UINT eventType; HWND hWnd; - struct EVENT_DATA_EX* firstEventData; - struct EVENT_DATA_EX* firstShowEventData; - struct EVENT_DATA_EX* lastEventData; + EVENT_DATA_EX *firstEventData; + EVENT_DATA_EX *firstShowEventData; + EVENT_DATA_EX *lastEventData; long countEvent; long iSeconds; }; @@ -215,13 +217,12 @@ struct PLUGIN_DATA //---External Procedure Definitions int PopupShow(MCONTACT hContact, MEVENT hEvent, UINT eventType); -int PopupUpdate(MCONTACT hContact, MEVENT hEvent); +int PopupUpdate(PLUGIN_DATA &pdata, MEVENT hEvent); int PopupAct(HWND hWnd, UINT mask, PLUGIN_DATA *pdata); int OptionsAdd(WPARAM addInfo, LPARAM); int Opt_DisableNEN(BOOL Status); int MenuitemInit(BOOL bStatus); int MenuitemUpdate(BOOL bStatus); -int NumberPopupData(MCONTACT hContact, UINT eventType); int CheckMsgWnd(MCONTACT hContact); PLUGIN_DATA* PU_GetByContact(MCONTACT hContact, UINT eventType); -- cgit v1.2.3