From 8a13e4ebf7cb38008a87cd908d44161b216f5db9 Mon Sep 17 00:00:00 2001 From: danieldg Date: Sat, 17 Oct 2009 02:43:14 +0000 Subject: Add ModeHandler::cull() for auto-deletion, fixes call of virtual method on partially-destructed object git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11883 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/mode.h | 1 + src/mode.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/mode.h b/include/mode.h index a9b0da656..81858a823 100644 --- a/include/mode.h +++ b/include/mode.h @@ -172,6 +172,7 @@ class CoreExport ModeHandler : public classbase * @param type Type of the mode (MODETYPE_USER or MODETYPE_CHANNEL) */ ModeHandler(Module* me, const std::string& name, char modeletter, ParamSpec params, ModeType type); + virtual bool cull(); virtual ~ModeHandler(); /** * Returns true if the mode is a list mode diff --git a/src/mode.cpp b/src/mode.cpp index 03d0b5269..144ddee72 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -11,8 +11,6 @@ * --------------------------------------------------- */ -/* $Core */ - #include "inspircd.h" #include "inspstring.h" @@ -55,10 +53,16 @@ ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modelett { } +bool ModeHandler::cull() +{ + ServerInstance->Modes->DelMode(this); + return true; +} + ModeHandler::~ModeHandler() { - if (ServerInstance) - ServerInstance->Modes->DelMode(this); + if (ServerInstance && ServerInstance->Modes->FindMode(mode, m_type) == this) + ServerInstance->Logs->Log("MODE", DEBUG, "ERROR: Destructor for mode %c called while not culled", mode); } bool ModeHandler::IsListMode() @@ -660,7 +664,7 @@ bool ModeParser::DelMode(ModeHandler* mh) mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL; pos = (mh->GetModeChar()-65) | mask; - if (!modehandlers[pos]) + if (modehandlers[pos] != mh) return false; /* Note: We can't stack here, as we have modes potentially being removed across many different channels. @@ -1023,6 +1027,6 @@ ModeParser::ModeParser() ModeParser::~ModeParser() { ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL); - if (mh) + if (mh && mh->cull()) delete mh; } -- cgit v1.2.3