diff options
author | Adam <Adam@anope.org> | 2014-08-24 16:39:04 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2014-08-24 16:39:04 -0400 |
commit | bf8f62c32d6c66e38c167e6ca0ac59d29db52326 (patch) | |
tree | ffdd06b244fcd38eca5956c7f9143f76ddcaaf5e | |
parent | d417241a5b87e1e717755aa851ba0977857db873 (diff) |
Change Channel::GetModeList to return a copy of the mode list, not a
pair of lower/upper bound iterators.
Sometimes when iterating the list, like in cs_mode, we can modify the
contents of it, which combined with mlock always agressively trying to
readd modes to it can do bad things.
-rw-r--r-- | include/channels.h | 4 | ||||
-rw-r--r-- | modules/commands/cs_akick.cpp | 6 | ||||
-rw-r--r-- | modules/commands/cs_mode.cpp | 13 | ||||
-rw-r--r-- | modules/m_xmlrpc_main.cpp | 18 | ||||
-rw-r--r-- | modules/pseudoclients/botserv.cpp | 6 | ||||
-rw-r--r-- | modules/webcpanel/pages/chanserv/modes.cpp | 6 | ||||
-rw-r--r-- | src/channels.cpp | 45 |
7 files changed, 49 insertions, 49 deletions
diff --git a/include/channels.h b/include/channels.h index cc30d2030..9bc6c27c6 100644 --- a/include/channels.h +++ b/include/channels.h @@ -242,9 +242,9 @@ class CoreExport Channel : public Base, public Extensible /** Get a list of modes on a channel * @param name A mode name to get the list of - * @return a pair of iterators for the beginning and end of the list + * @return a vector of the list mode entries */ - std::pair<ModeList::iterator, ModeList::iterator> GetModeList(const Anope::string &name); + std::vector<Anope::string> GetModeList(const Anope::string &name); /** Get a string of the modes set on this channel * @param complete Include mode parameters diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp index 873b1cb43..1fac25335 100644 --- a/modules/commands/cs_akick.cpp +++ b/modules/commands/cs_akick.cpp @@ -71,10 +71,10 @@ class CommandCSAKick : public Command /* Check excepts BEFORE we get this far */ if (ci->c) { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = ci->c->GetModeList("EXCEPT"); - for (; modes.first != modes.second; ++modes.first) + std::vector<Anope::string> modes = ci->c->GetModeList("EXCEPT"); + for (unsigned int i = 0; i < modes.size(); ++i) { - if (Anope::Match(modes.first->second, mask)) + if (Anope::Match(modes[i], mask)) { source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str()); return; diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 7f22d1e26..d5c356fa4 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -615,15 +615,10 @@ class CommandCSMode : public Command } else { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = ci->c->GetModeList(cm->name); - for (; its.first != its.second;) - { - const Anope::string &mask = its.first->second; - ++its.first; - - if (Anope::Match(mask, param)) - ci->c->RemoveMode(NULL, cm, mask); - } + std::vector<Anope::string> v = ci->c->GetModeList(cm->name); + for (unsigned j = 0; j < v.size(); ++j) + if (Anope::Match(v[j], param)) + ci->c->RemoveMode(NULL, cm, v[j]); } } } diff --git a/modules/m_xmlrpc_main.cpp b/modules/m_xmlrpc_main.cpp index 1a496c65c..13645bc98 100644 --- a/modules/m_xmlrpc_main.cpp +++ b/modules/m_xmlrpc_main.cpp @@ -155,21 +155,21 @@ class MyXMLRPCEvent : public XMLRPCEvent { request.reply("bancount", stringify(c->HasMode("BAN"))); int count = 0; - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList("BAN"); - for (; its.first != its.second; ++its.first) - request.reply("ban" + stringify(++count), iface->Sanitize(its.first->second)); + std::vector<Anope::string> v = c->GetModeList("BAN"); + for (unsigned int i = 0; i < v.size(); ++i) + request.reply("ban" + stringify(++count), iface->Sanitize(v[i])); request.reply("exceptcount", stringify(c->HasMode("EXCEPT"))); count = 0; - its = c->GetModeList("EXCEPT"); - for (; its.first != its.second; ++its.first) - request.reply("except" + stringify(++count), iface->Sanitize(its.first->second)); + v = c->GetModeList("EXCEPT"); + for (unsigned int i = 0; i < v.size(); ++i) + request.reply("except" + stringify(++count), iface->Sanitize(v[i])); request.reply("invitecount", stringify(c->HasMode("INVITEOVERRIDE"))); count = 0; - its = c->GetModeList("INVITEOVERRIDE"); - for (; its.first != its.second; ++its.first) - request.reply("invite" + stringify(++count), iface->Sanitize(its.first->second)); + v = c->GetModeList("INVITEOVERRIDE"); + for (unsigned int i = 0; i < v.size(); ++i) + request.reply("invite" + stringify(++count), iface->Sanitize(v[i])); Anope::string users; for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp index 48d604a6c..55c57b974 100644 --- a/modules/pseudoclients/botserv.cpp +++ b/modules/pseudoclients/botserv.cpp @@ -56,12 +56,12 @@ class BotServCore : public Module BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL; if (bi && Config->GetModule(this)->Get<bool>("smartjoin")) { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN"); + std::vector<Anope::string> bans = c->GetModeList("BAN"); /* We check for bans */ - for (; bans.first != bans.second; ++bans.first) + for (unsigned int i = 0; i < bans.size(); ++i) { - Entry ban("BAN", bans.first->second); + Entry ban("BAN", bans[i]); if (ban.Matches(user)) c->RemoveMode(NULL, "BAN", ban.GetMask()); } diff --git a/modules/webcpanel/pages/chanserv/modes.cpp b/modules/webcpanel/pages/chanserv/modes.cpp index d5b111708..e01239f58 100644 --- a/modules/webcpanel/pages/chanserv/modes.cpp +++ b/modules/webcpanel/pages/chanserv/modes.cpp @@ -94,9 +94,9 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements); } - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> ml = c->GetModeList(cm->name); - for (; ml.first != ml.second; ++ml.first) - replacements["MASKS"] = HTTPUtils::Escape(ml.first->second); + std::vector<Anope::string> v = c->GetModeList(cm->name); + for (unsigned int i = 0; i < v.size(); ++i) + replacements["MASKS"] = HTTPUtils::Escape(v[i]); } Page.Serve(server, page_name, client, message, reply, replacements); diff --git a/src/channels.cpp b/src/channels.cpp index d5ed0aa44..0ef8cf532 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -202,9 +202,9 @@ size_t Channel::HasMode(const Anope::string &mname, const Anope::string ¶m) { if (param.empty()) return modes.count(mname); - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = this->GetModeList(mname); - for (; its.first != its.second; ++its.first) - if (its.first->second.equals_ci(param)) + std::vector<Anope::string> v = this->GetModeList(mname); + for (unsigned int i = 0; i < v.size(); ++i) + if (v[i].equals_ci(param)) return 1; return 0; } @@ -240,12 +240,20 @@ const Channel::ModeList &Channel::GetModes() const return this->modes; } -std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::GetModeList(const Anope::string &mname) +template<typename F, typename S> +struct second { - Channel::ModeList::iterator it = this->modes.find(mname), it_end = it; - if (it != this->modes.end()) - it_end = this->modes.upper_bound(mname); - return std::make_pair(it, it_end); + S operator()(const std::pair<F, S> &p) + { + return p.second; + } +}; + +std::vector<Anope::string> Channel::GetModeList(const Anope::string &mname) +{ + std::vector<Anope::string> r; + std::transform(modes.lower_bound(mname), modes.upper_bound(mname), std::back_inserter(r), second<Anope::string, Anope::string>()); + return r; } void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) @@ -363,11 +371,10 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const if (cm->type == MODE_LIST) { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = this->GetModeList(cm->name); - for (; its.first != its.second; ++its.first) - if (param.equals_ci(its.first->second)) + for (Channel::ModeList::iterator it = modes.lower_bound(cm->name), it_end = modes.upper_bound(cm->name); it != it_end; ++it) + if (param.equals_ci(it->second)) { - this->modes.erase(its.first); + this->modes.erase(it); break; } } @@ -715,11 +722,10 @@ bool Channel::MatchesList(User *u, const Anope::string &mode) if (!this->HasMode(mode)) return false; - - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> m = this->GetModeList(mode); - for (; m.first != m.second; ++m.first) + std::vector<Anope::string> v = this->GetModeList(mode); + for (unsigned i = 0; i < v.size(); ++i) { - Entry e(mode, m.first->second); + Entry e(mode, v[i]); if (e.Matches(u)) return true; } @@ -872,11 +878,10 @@ bool Channel::Unban(User *u, const Anope::string &mode, bool full) bool ret = false; - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = this->GetModeList(mode); - for (; bans.first != bans.second;) + std::vector<Anope::string> v = this->GetModeList(mode); + for (unsigned int i = 0; i < v.size(); ++i) { - Entry ban(mode, bans.first->second); - ++bans.first; + Entry ban(mode, v[i]); if (ban.Matches(u, full)) { this->RemoveMode(NULL, mode, ban.GetMask()); |