From b28782c4a3cd52587d61541bcca4e0b217685c54 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Sun, 17 May 2015 18:00:42 +0200 Subject: [PATCH] Fix incorrect iterator use leading to prematurely exiting loops when quitting users while looping the local user list --- src/inspircd.cpp | 4 ++-- src/modules/m_close.cpp | 4 +++- src/modules/m_jumpserver.cpp | 4 +++- src/modules/m_nationalchars.cpp | 4 +++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/inspircd.cpp b/src/inspircd.cpp index cb2b5db9d..5dfcca6d9 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -110,8 +110,8 @@ void InspIRCd::Cleanup() /* Close all client sockets, or the new process inherits them */ const UserManager::LocalList& list = Users.GetLocalUsers(); - for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i) - Users->QuitUser(*i, "Server shutdown"); + while (!list.empty()) + Users->QuitUser(list.front(), "Server shutdown"); GlobalCulls.Apply(); Modules->UnloadAll(); diff --git a/src/modules/m_close.cpp b/src/modules/m_close.cpp index f3c751f17..3f0eedaaf 100644 --- a/src/modules/m_close.cpp +++ b/src/modules/m_close.cpp @@ -36,9 +36,11 @@ class CommandClose : public Command std::map closed; const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); - for (UserManager::LocalList::const_iterator u = list.begin(); u != list.end(); ++u) + for (UserManager::LocalList::const_iterator u = list.begin(); u != list.end(); ) { + // Quitting the user removes it from the list LocalUser* user = *u; + ++u; if (user->registered != REG_ALL) { ServerInstance->Users->QuitUser(user, "Closing all unknown connections per request"); diff --git a/src/modules/m_jumpserver.cpp b/src/modules/m_jumpserver.cpp index 599144448..e9c07f45f 100644 --- a/src/modules/m_jumpserver.cpp +++ b/src/modules/m_jumpserver.cpp @@ -109,9 +109,11 @@ class CommandJumpserver : public Command { /* Redirect everyone but the oper sending the command */ const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); - for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i) + for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ) { + // Quitting the user removes it from the list LocalUser* t = *i; + ++i; if (!t->IsOper()) { t->WriteNumeric(RPL_REDIR, "%s %d :Please use this Server/Port instead", parameters[0].c_str(), GetPort(t)); diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index f77899ad4..8e74ee3e6 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -292,10 +292,12 @@ class ModuleNationalChars : public Module return; const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); - for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ++iter) + for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ) { /* Fix by Brain: Dont quit UID users */ + // Quitting the user removes it from the list User* n = *iter; + ++iter; if (!isdigit(n->nick[0]) && !ServerInstance->IsNick(n->nick)) ServerInstance->Users->QuitUser(n, message); } -- 2.39.5