From 79cdf170d2ab6c5378cfbf61d5c8888a4c666190 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 28 Dec 2015 21:25:48 +0100 Subject: Use the configured encoding value when decoding received messages --- louloulibs/xmpp/xmpp_stanza.cpp | 16 ++++++++-------- louloulibs/xmpp/xmpp_stanza.hpp | 2 +- src/bridge/bridge.cpp | 40 ++++++++++++++++++++++++++++++++++------ src/bridge/bridge.hpp | 4 ++-- tests/database.cpp | 6 ++++++ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/louloulibs/xmpp/xmpp_stanza.cpp b/louloulibs/xmpp/xmpp_stanza.cpp index f247436..407e631 100644 --- a/louloulibs/xmpp/xmpp_stanza.cpp +++ b/louloulibs/xmpp/xmpp_stanza.cpp @@ -84,6 +84,14 @@ std::string xml_unescape(const std::string& data) return res; } +std::string sanitize(const std::string& data, const std::string& encoding) +{ + if (utils::is_valid_utf8(data.data())) + return xml_escape(utils::remove_invalid_xml_chars(data)); + else + return xml_escape(utils::remove_invalid_xml_chars(utils::convert_to_utf8(data, encoding.data()))); +} + XmlNode::XmlNode(const std::string& name, XmlNode* parent): parent(parent) { @@ -259,14 +267,6 @@ std::string& XmlNode::operator[](const std::string& name) return this->attributes[name]; } -std::string sanitize(const std::string& data) -{ - if (utils::is_valid_utf8(data.data())) - return xml_escape(utils::remove_invalid_xml_chars(data)); - else - return xml_escape(utils::remove_invalid_xml_chars(utils::convert_to_utf8(data, "ISO-8859-1"))); -} - std::ostream& operator<<(std::ostream& os, const XmlNode& node) { return os << node.to_string(); diff --git a/louloulibs/xmpp/xmpp_stanza.hpp b/louloulibs/xmpp/xmpp_stanza.hpp index bdc937f..77ab206 100644 --- a/louloulibs/xmpp/xmpp_stanza.hpp +++ b/louloulibs/xmpp/xmpp_stanza.hpp @@ -8,7 +8,7 @@ std::string xml_escape(const std::string& data); std::string xml_unescape(const std::string& data); -std::string sanitize(const std::string& data); +std::string sanitize(const std::string& data, const std::string& encoding = "ISO-8859-1"); /** * Represent an XML node. It has diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 55f4c51..4c97a91 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -9,11 +9,35 @@ #include #include #include +#include using namespace std::string_literals; static const char* action_prefix = "\01ACTION "; + +static std::string out_encoding_for(const Bridge& bridge, const Iid& iid) +{ +#ifdef USE_DATABASE + const auto jid = bridge.get_bare_jid(); + auto options = Database::get_irc_channel_options_with_server_default(jid, iid.get_server(), iid.get_local()); + return options.encodingOut.value(); +#else + return {"ISO-8859-1"}; +#endif +} + +static std::string in_encoding_for(const Bridge& bridge, const Iid& iid) +{ +#ifdef USE_DATABASE + const auto jid = bridge.get_bare_jid(); + auto options = Database::get_irc_channel_options_with_server_default(jid, iid.get_server(), iid.get_local()); + return options.encodingIn.value(); +#else + return {"ISO-8859-1"}; +#endif +} + Bridge::Bridge(const std::string& user_jid, BiboumiComponent& xmpp, std::shared_ptr poller): user_jid(user_jid), xmpp(xmpp), @@ -75,13 +99,13 @@ std::string Bridge::get_bare_jid() const return jid.local + "@" + jid.domain; } -Xmpp::body Bridge::make_xmpp_body(const std::string& str) +Xmpp::body Bridge::make_xmpp_body(const std::string& str, const std::string& encoding) { std::string res; if (utils::is_valid_utf8(str.c_str())) res = str; else - res = utils::convert_to_utf8(str, "ISO-8859-1"); + res = utils::convert_to_utf8(str, encoding.data()); return irc_format_to_xhtmlim(res); } @@ -531,9 +555,10 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std void Bridge::send_message(const Iid& iid, const std::string& nick, const std::string& body, const bool muc) { + const auto encoding = in_encoding_for(*this, iid); if (muc) this->xmpp.send_muc_message(std::to_string(iid), nick, - this->make_xmpp_body(body), this->user_jid); + this->make_xmpp_body(body, encoding), this->user_jid); else { std::string target = std::to_string(iid); @@ -544,7 +569,7 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st target = it->second; fulljid = true; } - this->xmpp.send_message(target, this->make_xmpp_body(body), + this->xmpp.send_message(target, this->make_xmpp_body(body, encoding), this->user_jid, "chat", fulljid); } } @@ -590,7 +615,9 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho } else body = msg; - this->xmpp.send_message(from, this->make_xmpp_body(body), this->user_jid, "chat"); + + const auto encoding = in_encoding_for(*this, {from}); + this->xmpp.send_message(from, this->make_xmpp_body(body, encoding), this->user_jid, "chat"); } void Bridge::send_user_join(const std::string& hostname, @@ -609,7 +636,8 @@ void Bridge::send_user_join(const std::string& hostname, void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string& topic) { - this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server("%" + hostname), this->make_xmpp_body(topic), this->user_jid); + const auto encoding = in_encoding_for(*this, {chan_name + '%' + hostname}); + this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server("%" + hostname), this->make_xmpp_body(topic, encoding), this->user_jid); } std::string Bridge::get_own_nick(const Iid& iid) diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index e73bd19..c030ed8 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -49,7 +49,7 @@ public: const std::string& get_jid() const; std::string get_bare_jid() const; - static Xmpp::body make_xmpp_body(const std::string& str); + static Xmpp::body make_xmpp_body(const std::string& str, const std::string& encodin = "ISO-8859-1"); /*** ** ** From XMPP to IRC. @@ -108,7 +108,7 @@ public: /** * Send a message corresponding to a server NOTICE, the from attribute - * should be juste the server hostname@irc.component. + * should be juste the server hostname. */ void send_xmpp_message(const std::string& from, const std::string& author, const std::string& msg); /** diff --git a/tests/database.cpp b/tests/database.cpp index 5d557fd..b059d0d 100644 --- a/tests/database.cpp +++ b/tests/database.cpp @@ -83,6 +83,12 @@ TEST_CASE("Database") THEN("we get the channel option") CHECK(r.encodingIn == "channelEncoding"); } + WHEN("we fetch that option, with no channel specified") + { + auto r = Database::get_irc_channel_options_with_server_default(owner, server, ""); + THEN("we get the server option") + CHECK(r.encodingIn == "serverEncoding"); + } } } -- cgit v1.2.3