From f05b9ef60098500061d8754ddd74f48449b03d49 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 20 Jun 2011 13:30:14 -0400 Subject: [PATCH] Fixed crash on plugin unload when two cmds exist with same name, different casing (bug 4698, r=Fyren). --- core/ConCmdManager.cpp | 75 ++++++++++++++++++++---------------------- core/ConCmdManager.h | 10 +++++- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/core/ConCmdManager.cpp b/core/ConCmdManager.cpp index 119f2fd1..29ad4ed3 100644 --- a/core/ConCmdManager.cpp +++ b/core/ConCmdManager.cpp @@ -226,30 +226,38 @@ void ConCmdManager::SetCommandClient(int client) m_CmdClient = client + 1; } +ConCmdInfo *ConCmdManager::FindInTrie(const char *name) +{ + ConCmdInfo *pInfo; + if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo)) + return NULL; + return pInfo; +} + +ConCmdList::iterator ConCmdManager::FindInList(const char *cmd) +{ + List::iterator iter = m_CmdList.begin(); + + while (iter != m_CmdList.end()) + { + if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0) + break; + iter++; + } + + return iter; +} + ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type) { ConCmdInfo *pInfo; - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) + if ((pInfo = FindInTrie(cmd)) == NULL) { - List::iterator iter; - - pInfo = NULL; - iter = m_CmdList.begin(); - while (iter != m_CmdList.end()) - { - if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0) - { - pInfo = (*iter); - break; - } - iter++; - } - - if (pInfo == NULL) - { + ConCmdList::iterator item = FindInList(cmd); + if (item == m_CmdList.end()) return type; - } + pInfo = *item; } cell_t result = type; @@ -314,35 +322,20 @@ void ConCmdManager::InternalDispatch(const CCommand &command) */ const char *cmd = g_HL2.CurrentCommandName(); - ConCmdInfo *pInfo; - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) + ConCmdInfo *pInfo = FindInTrie(cmd); + if (pInfo == NULL) { /* Unfortunately, we now have to do a slow lookup because Valve made client commands * case-insensitive. We can't even use our sortedness. */ if (client == 0 && !engine->IsDedicatedServer()) - { return; - } - List::iterator iter; + ConCmdList::iterator item = FindInList(cmd); + if (item == m_CmdList.end()) + return; - pInfo = NULL; - iter = m_CmdList.begin(); - while (iter != m_CmdList.end()) - { - if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0) - { - pInfo = (*iter); - break; - } - iter++; - } - - if (pInfo == NULL) - { - return; - } + pInfo = *item; } /* This is a hack to prevent say triggers from firing on messages that were @@ -916,6 +909,10 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri ConCmdInfo *pInfo; if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo)) { + ConCmdList::iterator item = FindInList(name); + if (item != m_CmdList.end()) + return *item; + pInfo = new ConCmdInfo(); /* Find the commandopan */ ConCommand *pCmd = FindCommand(name); diff --git a/core/ConCmdManager.h b/core/ConCmdManager.h index 76c74717..448ff953 100644 --- a/core/ConCmdManager.h +++ b/core/ConCmdManager.h @@ -92,6 +92,8 @@ struct ConCmdInfo bool is_admin_set; /**< Whether or not admin info is set */ }; +typedef List ConCmdList; + class ConCmdManager : public SMGlobalClass, public IRootConsoleCommand, @@ -139,6 +141,12 @@ private: void RemoveConCmds(List &cmdlist); void RemoveConCmds(List &cmdlist, IPluginContext *pContext); bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin); + + // Case insensitive + ConCmdList::iterator FindInList(const char *name); + + // Case sensitive + ConCmdInfo *FindInTrie(const char *name); public: inline int GetCommandClient() { @@ -151,7 +159,7 @@ public: private: Trie *m_pCmds; /* command lookup */ Trie *m_pCmdGrps; /* command group lookup */ - List m_CmdList; /* command list */ + ConCmdList m_CmdList; /* command list */ int m_CmdClient; /* current client */ BaseStringTable m_Strings; /* string table */ };