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 /src | |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.cpp | 45 |
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 ¶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()); |