summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2023-08-08 09:38:54 +0200
committerSébastien Helleu <flashcode@flashtux.org>2023-08-08 09:38:54 +0200
commitc6b18e96544273de0c93d32295c5dff00430c11e (patch)
tree4de5bb45f7ffdc15eba0b19de3b8ad194ad4b2cf
parentff41a79aa99cbb78e22c7c4ff139ec6c5260f39c (diff)
downloadweechat-c6b18e96544273de0c93d32295c5dff00430c11e.zip
relay: fix display of IRC CTCP messages received from client (issue #1986)
-rw-r--r--ChangeLog.adoc1
-rw-r--r--src/plugins/relay/irc/relay-irc.c102
-rw-r--r--tests/unit/plugins/relay/irc/test-relay-irc.cpp68
3 files changed, 161 insertions, 10 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index 463842bf5..2d31e68de 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -27,6 +27,7 @@ New features::
* irc: build dynamically the list of CTCPs supported in reply to "CTCP CLIENTINFO" (issue #1974)
* irc: remove Git revision and compilation date from CTCP VERSION reply (issue #1974)
* irc: remove default CTCP replies FINGER and USERINFO (issue #1974)
+ * relay: fix display of IRC CTCP messages received from client (issue #1986)
* trigger: add options `-o`, `-ol`, `-i` and `-il` in command `/trigger list` (issue #1953)
Bug fixes::
diff --git a/src/plugins/relay/irc/relay-irc.c b/src/plugins/relay/irc/relay-irc.c
index fdc6c79a1..afe44ccc5 100644
--- a/src/plugins/relay/irc/relay-irc.c
+++ b/src/plugins/relay/irc/relay-irc.c
@@ -1582,6 +1582,53 @@ relay_irc_recv_command_capab (struct t_relay_client *client,
}
/*
+ * Parses CTCP message and return CTCP type and parameters.
+ * If message is not a valid CTCP format, type and parameters are set to NULL.
+ *
+ * Examples:
+ *
+ * message | type | params
+ * --------------------------|-----------|-----------
+ * "\01ACTION is testing\01" | "ACTION" | "is testing"
+ * "\01VERSION\01" | "VERSION" | NULL
+ * "\01VERSION" | NULL | NULL
+ * "test" | NULL | NULL
+ */
+
+void
+relay_irc_parse_ctcp (const char *message, char **ctcp_type, char **ctcp_params)
+{
+ const char *pos_space, *pos_end;
+
+ if (!ctcp_type || !ctcp_params)
+ return;
+
+ *ctcp_type = NULL;
+ *ctcp_params = NULL;
+
+ if (!message)
+ return;
+
+ if (message[0] != '\01')
+ return;
+
+ pos_end = strrchr (message + 1, '\01');
+ if (!pos_end)
+ return;
+
+ pos_space = strchr (message, ' ' );
+ if (pos_space && (pos_space < pos_end))
+ {
+ *ctcp_type = weechat_strndup (message + 1, pos_space - message - 1);
+ *ctcp_params = weechat_strndup (pos_space + 1, pos_end - pos_space - 1);
+ }
+ else
+ {
+ *ctcp_type = weechat_strndup (message + 1, pos_end - message - 1);
+ }
+}
+
+/*
* Reads one message from client.
*/
@@ -1595,7 +1642,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
char str_time[128], str_signal[128], str_server_channel[256], *nick;
char str_param[128], *str_args, *version, str_command[128], **params;
char *pos, *password, *irc_is_channel, *info, *error, *str_cmd_lower;
- char modifier_data[128], *new_data;
+ char modifier_data[128], *new_data, *ctcp_type, *ctcp_params;
long num_params;
int i, redirect_msg;
@@ -1933,26 +1980,61 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
{
str_args = weechat_string_rebuild_split_string (
(const char **)params, " ", 1, -1);
+ relay_irc_parse_ctcp (str_args, &ctcp_type, &ctcp_params);
irc_is_channel = weechat_info_get ("irc_is_channel", params[0]);
if (irc_is_channel && (strcmp (irc_is_channel, "1") == 0))
{
- relay_irc_input_send (client, params[0],
- "priority_high,user_message",
- "%s",
- (str_args) ? str_args : "");
+ if (ctcp_type)
+ {
+ relay_irc_input_send (client, NULL,
+ "priority_high",
+ "/ctcp %s %s%s%s",
+ params[0],
+ ctcp_type,
+ (ctcp_params) ? " " : "",
+ (ctcp_params) ? ctcp_params : "");
+ }
+ else
+ {
+ relay_irc_input_send (client, params[0],
+ "priority_high,user_message",
+ "%s",
+ (str_args) ? str_args : "");
+ }
}
else
{
- relay_irc_input_send (client, NULL,
- "priority_high",
- "/query %s %s",
- params[0],
- (str_args) ? str_args : "");
+ if (ctcp_type)
+ {
+ relay_irc_input_send (client, NULL,
+ "priority_high",
+ "/query %s",
+ params[0]);
+ relay_irc_input_send (client, NULL,
+ "priority_high",
+ "/ctcp %s %s%s%s",
+ params[0],
+ ctcp_type,
+ (ctcp_params) ? " " : "",
+ (ctcp_params) ? ctcp_params : "");
+ }
+ else
+ {
+ relay_irc_input_send (client, NULL,
+ "priority_high",
+ "/query %s %s",
+ params[0],
+ (str_args) ? str_args : "");
+ }
}
if (str_args)
free (str_args);
if (irc_is_channel)
free (irc_is_channel);
+ if (ctcp_type)
+ free (ctcp_type);
+ if (ctcp_params)
+ free (ctcp_params);
}
}
else if (!relay_irc_command_ignored (irc_command))
diff --git a/tests/unit/plugins/relay/irc/test-relay-irc.cpp b/tests/unit/plugins/relay/irc/test-relay-irc.cpp
index f1fb2e531..13fc92dac 100644
--- a/tests/unit/plugins/relay/irc/test-relay-irc.cpp
+++ b/tests/unit/plugins/relay/irc/test-relay-irc.cpp
@@ -49,6 +49,8 @@ extern void relay_irc_sendf (struct t_relay_client *client,
const char *format, ...);
extern void relay_irc_parse_cap_message (struct t_relay_client *client,
struct t_hashtable *parsed_msg);
+extern void relay_irc_parse_ctcp (const char *message,
+ char **ctcp_type, char **ctcp_params);
extern int relay_irc_tag_relay_client_id (const char *tags);
extern void relay_irc_input_send (struct t_relay_client *client,
const char *irc_channel,
@@ -814,6 +816,72 @@ TEST(RelayIrcWithClient, RelayIrcRecvCommandCapab)
/*
* Tests functions:
+ * relay_irc_parse_ctcp
+ */
+
+TEST(RelayIrcWithClient, RelayIrcParseCtcp)
+{
+ char *ctcp_type, *ctcp_params;
+
+ relay_irc_parse_ctcp (NULL, NULL, NULL);
+ relay_irc_parse_ctcp ("test", NULL, NULL);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp (NULL, &ctcp_type, &ctcp_params);
+ POINTERS_EQUAL(NULL, ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("\01ACTION is testing\01", &ctcp_type, &ctcp_params);
+ STRCMP_EQUAL("ACTION", ctcp_type);
+ STRCMP_EQUAL("is testing", ctcp_params);
+ free (ctcp_type);
+ free (ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("\01ACTION is testing \01 extra", &ctcp_type, &ctcp_params);
+ STRCMP_EQUAL("ACTION", ctcp_type);
+ STRCMP_EQUAL(" is testing ", ctcp_params);
+ free (ctcp_type);
+ free (ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("\01VERSION\01", &ctcp_type, &ctcp_params);
+ STRCMP_EQUAL("VERSION", ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+ free (ctcp_type);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("\01ACTION is testing", &ctcp_type, &ctcp_params);
+ POINTERS_EQUAL(NULL, ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("\01VERSION", &ctcp_type, &ctcp_params);
+ POINTERS_EQUAL(NULL, ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("test", &ctcp_type, &ctcp_params);
+ POINTERS_EQUAL(NULL, ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+
+ ctcp_type = (char *)0x01;
+ ctcp_params = (char *)0x01;
+ relay_irc_parse_ctcp ("", &ctcp_type, &ctcp_params);
+ POINTERS_EQUAL(NULL, ctcp_type);
+ POINTERS_EQUAL(NULL, ctcp_params);
+}
+
+/*
+ * Tests functions:
* relay_irc_recv
*/