From f99127478993b5c35f23c1ce973871ad93fef0ac Mon Sep 17 00:00:00 2001 From: psychon Date: Sun, 22 Mar 2009 19:05:34 +0000 Subject: [PATCH] Fix a crash bug with recursion in module calls This was found via partyline and notify_connect. notify_connect calls CZNC::Broadcast() in OnClientLogin() which calls the OnBroadcast() module call. When returning from this module calls, m_pUser and m_pClient was reset to NULL and all the following modules got their OnClientLogin() called with m_pUser and m_pClient set to NULL. This patch fixes this by resetting those vars to their old values instead to NULL when returning from a module call. This patch also fixes the bug that m_pUser and m_pClient in modules were reset to NULL after they caused a module call which called back into the current module. The fix looks similar to the other one (this one is the Modules.h part). git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1438 726aef4b-f618-498e-8847-2d620e286838 --- Modules.cpp | 12 ++++++++---- Modules.h | 2 ++ main.h | 16 +++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Modules.cpp b/Modules.cpp index 0c6e1a53..c6a6c089 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -22,15 +22,17 @@ for (unsigned int a = 0; a < size(); a++) { \ try { \ type* pMod = (type *) (*this)[a]; \ + CClient* pOldClient = pMod->GetClient(); \ pMod->SetClient(m_pClient); \ if (m_pUser) { \ + CUser* pOldUser = pMod->GetUser(); \ pMod->SetUser(m_pUser); \ pMod->func; \ - pMod->SetUser(NULL); \ + pMod->SetUser(pOldUser); \ } else { \ pMod->func; \ } \ - pMod->SetClient(NULL); \ + pMod->SetClient(pOldClient); \ } catch (CModule::EModException e) { \ if (e == CModule::UNLOAD) { \ UnloadModule((*this)[a]->GetModName()); \ @@ -47,15 +49,17 @@ try { \ type* pMod = (type*) (*this)[a]; \ CModule::EModRet e = CModule::CONTINUE; \ + CClient* pOldClient = pMod->GetClient(); \ pMod->SetClient(m_pClient); \ if (m_pUser) { \ + CUser* pOldUser = pMod->GetUser(); \ pMod->SetUser(m_pUser); \ e = pMod->func; \ - pMod->SetUser(NULL); \ + pMod->SetUser(pOldUser); \ } else { \ e = pMod->func; \ } \ - pMod->SetClient(NULL); \ + pMod->SetClient(pOldClient); \ if (e == CModule::HALTMODS) { \ break; \ } else if (e == CModule::HALTCORE) { \ diff --git a/Modules.h b/Modules.h index 04c67728..55331a2c 100644 --- a/Modules.h +++ b/Modules.h @@ -366,6 +366,8 @@ public: void SetUser(CUser* pUser) { m_pUser = pUser; } void SetClient(CClient* pClient) { m_pClient = pClient; } + CUser* GetUser() { return m_pUser; } + CClient* GetClient() { return m_pClient; } void UnloadAll(); diff --git a/main.h b/main.h index e4f62c30..6e1f4df7 100644 --- a/main.h +++ b/main.h @@ -33,15 +33,21 @@ if (macUSER) { \ CGlobalModules& GMods = CZNC::Get().GetModules(); \ CModules& UMods = macUSER->GetModules(); \ - GMods.SetUser(macUSER); GMods.SetClient(macCLIENT); \ + CUser* pOldGUser = GMods.GetUser(); \ + CClient* pOldGClient = GMods.GetClient(); \ + CClient* pOldUClient = UMods.GetClient(); \ + GMods.SetUser(macUSER); \ + GMods.SetClient(macCLIENT); \ UMods.SetClient(macCLIENT); \ if (GMods.macFUNC || UMods.macFUNC) { \ - GMods.SetUser(NULL); GMods.SetClient(NULL); \ - UMods.SetClient(NULL); \ + GMods.SetUser(pOldGUser); \ + GMods.SetClient(pOldGClient); \ + UMods.SetClient(pOldUClient); \ macEXITER; \ } \ - GMods.SetUser(NULL); GMods.SetClient(NULL); \ - UMods.SetClient(NULL); \ + GMods.SetUser(pOldGUser); \ + GMods.SetClient(pOldGClient); \ + UMods.SetClient(pOldUClient); \ } #else #define MODULECALL(macFUNC, macUSER, macCLIENT, macEXITER)