summaryrefslogtreecommitdiff
path: root/src/channels.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2014-08-24 16:39:04 -0400
committerAdam <Adam@anope.org>2014-08-24 16:39:04 -0400
commitbf8f62c32d6c66e38c167e6ca0ac59d29db52326 (patch)
treeffdd06b244fcd38eca5956c7f9143f76ddcaaf5e /src/channels.cpp
parentd417241a5b87e1e717755aa851ba0977857db873 (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.
Diffstat (limited to 'src/channels.cpp')
-rw-r--r--src/channels.cpp45
1 files changed, 25 insertions, 20 deletions
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 &param)
{
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());