Fixed crash on plugin unload when two cmds exist with same name, different casing (bug 4698, r=Fyren).

This commit is contained in:
David Anderson 2011-06-20 13:30:14 -04:00
parent 9a5f788807
commit 859678536f
2 changed files with 45 additions and 40 deletions

View File

@ -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<ConCmdInfo *>::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))
{
List<ConCmdInfo *>::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)
if ((pInfo = FindInTrie(cmd)) == 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<ConCmdInfo *>::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;
}
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);

View File

@ -92,6 +92,8 @@ struct ConCmdInfo
bool is_admin_set; /**< Whether or not admin info is set */
};
typedef List<ConCmdInfo *> ConCmdList;
class ConCmdManager :
public SMGlobalClass,
public IRootConsoleCommand,
@ -139,6 +141,12 @@ private:
void RemoveConCmds(List<CmdHook *> &cmdlist);
void RemoveConCmds(List<CmdHook *> &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<ConCmdInfo *> m_CmdList; /* command list */
ConCmdList m_CmdList; /* command list */
int m_CmdClient; /* current client */
BaseStringTable m_Strings; /* string table */
};