1
0
mirror of https://github.com/anope/anope.git synced 2026-07-03 09:53:12 +02:00

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.
This commit is contained in:
Adam
2014-08-24 16:39:04 -04:00
parent d417241a5b
commit bf8f62c32d
7 changed files with 49 additions and 49 deletions
+25 -20
View File
@@ -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());