summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/irc/irc-protocol.c5
-rw-r--r--src/plugins/irc/irc-server.c40
-rw-r--r--src/plugins/irc/irc-server.h1
-rw-r--r--src/plugins/irc/irc-upgrade.c14
-rw-r--r--tests/unit/plugins/irc/test-irc-protocol.cpp8
5 files changed, 50 insertions, 18 deletions
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 73424482a..c22fe28af 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -4004,6 +4004,11 @@ IRC_PROTOCOL_CALLBACK(005)
if (utf8mapping >= 0)
server->utf8mapping = utf8mapping;
}
+ else if (strcmp (params[i], "UTF8ONLY") == 0)
+ {
+ /* save utf8only */
+ server->utf8only = 1;
+ }
else if (strncmp (params[i], "CHANTYPES=", 10) == 0)
{
/* save chantypes */
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index a608a287b..0166e4a9e 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -1715,6 +1715,7 @@ irc_server_alloc (const char *name)
new_server->host_max_length = 0;
new_server->casemapping = IRC_SERVER_CASEMAPPING_RFC1459;
new_server->utf8mapping = IRC_SERVER_UTF8MAPPING_NONE;
+ new_server->utf8only = 0;
new_server->chantypes = NULL;
new_server->chanmodes = NULL;
new_server->monitor = 0;
@@ -2955,17 +2956,14 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
server->name);
}
-
- if (!irc_server_get_isupport_value (server, "UTF8ONLY"))
+ /*
+ * when UTF8ONLY is enabled, clients must not send non-UTF-8 data
+ * to the server; the charset encoding below is then done only if
+ * UTF8ONLY is *NOT* enabled
+ * (see: https://ircv3.net/specs/extensions/utf8-only)
+ */
+ if (!server->utf8only)
{
- /* "Clients implementing this specification MUST NOT send
- * non-UTF-8 data to the server once they have seen
- * this token."
- * "If a client implementing this specification sees this token,
- * they MUST set their outgoing encoding to UTF-8 without
- * requiring any user intervention."
- * -- https://ircv3.net/specs/extensions/utf8-only
- */
msg_encoded = irc_message_convert_charset (ptr_msg, pos_encode,
"charset_encode",
modifier_data);
@@ -3562,14 +3560,17 @@ irc_server_msgq_flush ()
irc_recv_msgq->server->name);
}
}
- if (!irc_server_get_isupport_value (irc_recv_msgq->server,
- "UTF8ONLY"))
+
+ /*
+ * when UTF8ONLY is enabled, servers must
+ * not relay content containing non-UTF-8
+ * data to clients; the charset decoding below
+ * is then done only if UTF8ONLY is *NOT*
+ * enabled
+ * (see: https://ircv3.net/specs/extensions/utf8-only)
+ */
+ if (!irc_recv_msgq->server->utf8only)
{
- /* "Servers publishing this token MUST NOT relay content
- * [...] containing non-UTF-8 data to clients"
- * -- https://ircv3.net/specs/extensions/utf8-only
- * Therefore, no need to decode, we are sure it is UTF-8.
- */
msg_decoded = irc_message_convert_charset (
ptr_msg, pos_decode,
"charset_decode", modifier_data);
@@ -5718,6 +5719,7 @@ irc_server_disconnect (struct t_irc_server *server, int switch_address,
server->host_max_length = 0;
server->casemapping = IRC_SERVER_CASEMAPPING_RFC1459;
server->utf8mapping = IRC_SERVER_UTF8MAPPING_NONE;
+ server->utf8only = 0;
if (server->chantypes)
{
free (server->chantypes);
@@ -6418,6 +6420,7 @@ irc_server_hdata_server_cb (const void *pointer, void *data,
WEECHAT_HDATA_VAR(struct t_irc_server, host_max_length, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, casemapping, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, utf8mapping, INTEGER, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_server, utf8only, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, chantypes, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, chanmodes, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, monitor, INTEGER, 0, NULL, NULL);
@@ -6800,6 +6803,8 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "utf8mapping_string", irc_server_utf8mapping_string[server->utf8mapping]))
return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "utf8only", server->utf8only))
+ return 0;
if (!weechat_infolist_new_var_string (ptr_item, "chantypes", server->chantypes))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "chanmodes", server->chanmodes))
@@ -7193,6 +7198,7 @@ irc_server_print_log ()
weechat_log_printf (" utf8mapping . . . . . . . : %d (%s)",
ptr_server->utf8mapping,
irc_server_utf8mapping_string[ptr_server->utf8mapping]);
+ weechat_log_printf (" utf8only. . . . . . . . . : %d", ptr_server->utf8only);
weechat_log_printf (" chantypes . . . . . . . . : '%s'", ptr_server->chantypes);
weechat_log_printf (" chanmodes . . . . . . . . : '%s'", ptr_server->chanmodes);
weechat_log_printf (" monitor . . . . . . . . . : %d", ptr_server->monitor);
diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h
index 3c3a574c9..cbfb05d82 100644
--- a/src/plugins/irc/irc-server.h
+++ b/src/plugins/irc/irc-server.h
@@ -248,6 +248,7 @@ struct t_irc_server
int host_max_length; /* max length of host (from msg 005) */
int casemapping; /* casemapping from msg 005 */
int utf8mapping; /* utf8mapping from msg 005 */
+ int utf8only; /* UTF-8 only? */
char *chantypes; /* chantypes from msg 005 (eg "&#") */
char *chanmodes; /* chanmodes from msg 005 */
/* (eg "beI,k,l,imnpstaqr") */
diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c
index 231eb8805..b717418ca 100644
--- a/src/plugins/irc/irc-upgrade.c
+++ b/src/plugins/irc/irc-upgrade.c
@@ -557,6 +557,20 @@ irc_upgrade_read_cb (const void *pointer, void *data,
irc_upgrade_current_server->utf8mapping = utf8mapping;
}
}
+ /* "utf8only" is new in WeeChat 4.0.0 */
+ if (weechat_infolist_search_var (infolist, "utf8only"))
+ {
+ irc_upgrade_current_server->utf8only = weechat_infolist_integer (infolist, "utf8only");
+ }
+ else
+ {
+ /* WeeChat <= 3.8 */
+ irc_upgrade_current_server->utf8only = (
+ irc_server_get_isupport_value (
+ irc_upgrade_current_server,
+ "UTF8ONLY")) ?
+ 1 : 0;
+ }
str = weechat_infolist_string (infolist, "chantypes");
if (str)
irc_upgrade_current_server->chantypes = strdup (str);
diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp
index c99ef13bb..97d6ebb25 100644
--- a/tests/unit/plugins/irc/test-irc-protocol.cpp
+++ b/tests/unit/plugins/irc/test-irc-protocol.cpp
@@ -65,7 +65,7 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities,
"CASEMAPPING=strict-rfc1459 LINELEN=4096 NICKLEN=30 MAXNICKLEN=31 " \
"USERLEN=16 HOSTLEN=32 CHANNELLEN=50 TOPICLEN=390 DEAF=D " \
"CHANTYPES=# CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz " \
- "MONITOR=100"
+ "MONITOR=100 UTF8MAPPING=rfc8265 UTF8ONLY"
#define IRC_ALL_CAPS "account-notify,away-notify,batch,cap-notify," \
"chghost,draft/multiline,extended-join,invite-notify,message-tags," \
"multi-prefix,server-time,setname,userhost-in-names"
@@ -2447,6 +2447,8 @@ TEST(IrcProtocolWithServer, 005_full)
POINTERS_EQUAL(NULL, ptr_server->chantypes);
POINTERS_EQUAL(NULL, ptr_server->chanmodes);
LONGS_EQUAL(0, ptr_server->monitor);
+ LONGS_EQUAL(IRC_SERVER_UTF8MAPPING_NONE, ptr_server->utf8mapping);
+ LONGS_EQUAL(0, ptr_server->utf8only);
POINTERS_EQUAL(NULL, ptr_server->isupport);
RECV(":server 005 alice " IRC_MSG_005 " :are supported");
@@ -2462,6 +2464,8 @@ TEST(IrcProtocolWithServer, 005_full)
STRCMP_EQUAL("#", ptr_server->chantypes);
STRCMP_EQUAL("eIbq,k,flj,CFLMPQScgimnprstuz", ptr_server->chanmodes);
LONGS_EQUAL(100, ptr_server->monitor);
+ LONGS_EQUAL(IRC_SERVER_UTF8MAPPING_RFC8265, ptr_server->utf8mapping);
+ LONGS_EQUAL(1, ptr_server->utf8only);
STRCMP_EQUAL(IRC_MSG_005, ptr_server->isupport);
/* check that realloc of info is OK if we receive the message again */
@@ -2478,6 +2482,8 @@ TEST(IrcProtocolWithServer, 005_full)
STRCMP_EQUAL("#", ptr_server->chantypes);
STRCMP_EQUAL("eIbq,k,flj,CFLMPQScgimnprstuz", ptr_server->chanmodes);
LONGS_EQUAL(100, ptr_server->monitor);
+ LONGS_EQUAL(IRC_SERVER_UTF8MAPPING_RFC8265, ptr_server->utf8mapping);
+ LONGS_EQUAL(1, ptr_server->utf8only);
STRCMP_EQUAL(IRC_MSG_005 " " IRC_MSG_005, ptr_server->isupport);
}