diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-12-07 10:53:53 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-12-07 10:53:53 +0100 |
commit | 374d7eb09877003acb433717fc20c488c5c87476 (patch) | |
tree | 92ca73c882a93fc9351ed5ae24a15dba027e219a /src/modules | |
parent | 91fe9afed5ee65f1d6dc1d0d3cdee628125f4d0d (diff) | |
parent | e114a7ec08836cdd8c005f320a7f372435b33786 (diff) |
Merge pull request #1110 from SaberUK/insp20+cap
[2.0] Fix CAP REQ to be atomic like the standard dictates.
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/m_cap.cpp | 23 | ||||
-rw-r--r-- | src/modules/m_cap.h | 5 |
2 files changed, 18 insertions, 10 deletions
diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index e9f4dae90..6b4387fdd 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -66,23 +66,28 @@ class CommandCAP : public Command while (cap_stream.GetToken(cap_)) { - Data.wanted.push_back(cap_); + // Whilst the handling of extraneous spaces is not currently defined in the CAP specification + // every single other implementation ignores extraneous spaces. Lets copy them for + // compatibility purposes. + trim(cap_); + if (!cap_.empty()) + Data.wanted.push_back(cap_); } reghold.set(user, 1); Data.Send(); - if (Data.ack.size() > 0) + if (Data.wanted.empty()) { - std::string AckResult = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined(); - user->WriteServ("CAP %s ACK :%s", user->nick.c_str(), AckResult.c_str()); + user->WriteServ("CAP %s ACK :%s", user->nick.c_str(), parameters[1].c_str()); + return CMD_SUCCESS; } - if (Data.wanted.size() > 0) - { - std::string NakResult = irc::stringjoiner(" ", Data.wanted, 0, Data.wanted.size() - 1).GetJoined(); - user->WriteServ("CAP %s NAK :%s", user->nick.c_str(), NakResult.c_str()); - } + // HACK: reset all of the caps which were enabled on this user because a cap request is atomic. + for (std::vector<std::pair<GenericCap*, int> >::iterator iter = Data.changed.begin(); iter != Data.changed.end(); ++iter) + iter->first->ext.set(user, iter->second); + + user->WriteServ("CAP %s NAK :%s", user->nick.c_str(), parameters[1].c_str()); } else if (subcommand == "END") { diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h index 409671f48..23cf8cf69 100644 --- a/src/modules/m_cap.h +++ b/src/modules/m_cap.h @@ -21,6 +21,8 @@ #ifndef M_CAP_H #define M_CAP_H +class GenericCap; + class CapEvent : public Event { public: @@ -35,6 +37,7 @@ class CapEvent : public Event CapEventType type; std::vector<std::string> wanted; std::vector<std::string> ack; + std::vector<std::pair<GenericCap*, int> > changed; // HACK: clean this up before 2.2 User* user; CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {} }; @@ -67,7 +70,7 @@ class GenericCap // we can handle this, so ACK it, and remove it from the wanted list data->ack.push_back(*it); data->wanted.erase(it); - ext.set(data->user, enablecap ? 1 : 0); + data->changed.push_back(std::make_pair(this, ext.set(data->user, enablecap ? 1 : 0))); break; } } |