From 0391f17f999618decffaf3c9261024ab04a33f63 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 21 Jun 2016 23:15:25 +0100 Subject: Add XEP-0106 support to the bridge This allows the user to join channels containing forbidden characters in the local part, like #r&d or #group/project. --- src/bridge/bridge.cpp | 17 +++++++++++------ src/irc/iid.cpp | 19 +++++++++++++++---- src/irc/iid.hpp | 1 + 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 3a7a147..87667db 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -685,7 +685,10 @@ void Bridge::send_user_join(const std::string& hostname, const std::string& chan std::string role; std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode); - this->xmpp.send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host, + std::string encoded_chan_name(chan_name); + xep0106::encode(encoded_chan_name); + + this->xmpp.send_user_join(encoded_chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host, affiliation, role, this->user_jid + "/" + resource, self); } @@ -701,8 +704,10 @@ void Bridge::send_topic(const std::string& hostname, const std::string& chan_nam const std::string& topic, const std::string& who, const std::string& resource) { - const auto encoding = in_encoding_for(*this, {chan_name + '%' + hostname}); - this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server( + std::string encoded_chan_name(chan_name); + xep0106::encode(encoded_chan_name); + const auto encoding = in_encoding_for(*this, {encoded_chan_name + '%' + hostname}); + this->xmpp.send_topic(encoded_chan_name + utils::empty_if_fixed_server( "%" + hostname), this->make_xmpp_body(topic, encoding), this->user_jid + "/" + resource, who); } @@ -884,13 +889,13 @@ void Bridge::generate_channel_join_for_resource(const Iid& iid, const std::strin if (user->nick != self->nick) { log_debug(user->nick); - this->send_user_join(iid.get_server(), iid.get_local(), + this->send_user_join(iid.get_server(), iid.get_encoded_local(), user.get(), user->get_most_significant_mode(irc->get_sorted_user_modes()), false, resource); } } - this->send_user_join(iid.get_server(), iid.get_local(), + this->send_user_join(iid.get_server(), iid.get_encoded_local(), self, self->get_most_significant_mode(irc->get_sorted_user_modes()), true, resource); - this->send_topic(iid.get_server(), iid.get_local(), channel->topic, channel->topic_author, resource); + this->send_topic(iid.get_server(), iid.get_encoded_local(), channel->topic, channel->topic_author, resource); } diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp index 66b66b7..0e2841e 100644 --- a/src/irc/iid.cpp +++ b/src/irc/iid.cpp @@ -3,6 +3,8 @@ #include +#include + Iid::Iid(const std::string& iid): is_channel(false), is_user(false) @@ -59,7 +61,9 @@ Iid::Iid(): void Iid::set_local(const std::string& loc) { - this->local = utils::tolower(loc); + std::string local(utils::tolower(loc)); + xep0106::decode(local); + this->local = local; } void Iid::set_server(const std::string& serv) @@ -72,6 +76,13 @@ const std::string& Iid::get_local() const return this->local; } +const std::string Iid::get_encoded_local() const +{ + std::string local(this->local); + xep0106::encode(local); + return local; +} + const std::string& Iid::get_server() const { return this->server; @@ -90,13 +101,13 @@ namespace std { const std::string to_string(const Iid& iid) { if (Config::get("fixed_irc_server", "").empty()) - return iid.get_local() + iid.get_sep() + iid.get_server(); + return iid.get_encoded_local() + iid.get_sep() + iid.get_server(); else { if (iid.get_sep() == "!") - return iid.get_local() + iid.get_sep(); + return iid.get_encoded_local() + iid.get_sep(); else - return iid.get_local(); + return iid.get_encoded_local(); } } } diff --git a/src/irc/iid.hpp b/src/irc/iid.hpp index 9747595..a55ae21 100644 --- a/src/irc/iid.hpp +++ b/src/irc/iid.hpp @@ -53,6 +53,7 @@ public: void set_local(const std::string& loc); void set_server(const std::string& serv); const std::string& get_local() const; + const std::string get_encoded_local() const; const std::string& get_server() const; bool is_channel; -- cgit v1.2.3