summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--src/plugins/relay/irc/relay-irc.c256
2 files changed, 126 insertions, 131 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index 4f248539a..4d9af0386 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -26,6 +26,7 @@ New features::
Bug fixes::
* irc: fix duplicated channels in autojoin option when autojoin_dynamic is enabled (issue #1795)
+ * relay: fix parsing of IRC messages received from clients (issue #1796)
[[v3.6]]
== Version 3.6 (2022-07-10)
diff --git a/src/plugins/relay/irc/relay-irc.c b/src/plugins/relay/irc/relay-irc.c
index e1555cba5..06945159f 100644
--- a/src/plugins/relay/irc/relay-irc.c
+++ b/src/plugins/relay/irc/relay-irc.c
@@ -1239,12 +1239,15 @@ relay_irc_hook_signals (struct t_relay_client *client)
void
relay_irc_recv_command_capab (struct t_relay_client *client,
- int argc, char **argv, char **argv_eol)
+ int num_params, const char **params)
{
- char str_capab[1024], *ptr_cap;
+ char str_capab[1024], *str_caps;
int i, capability, server_caps, num_caps_received, caps_ok;
- if (weechat_strcasecmp (argv[0], "ls") == 0)
+ if (num_params < 1)
+ return;
+
+ if (weechat_strcasecmp (params[0], "ls") == 0)
{
/* return the list of supported server capabilities */
str_capab[0] = '\0';
@@ -1262,40 +1265,40 @@ relay_irc_recv_command_capab (struct t_relay_client *client,
if (!RELAY_IRC_DATA(client, connected))
RELAY_IRC_DATA(client, cap_ls_received) = 1;
}
- else if (weechat_strcasecmp (argv[0], "req") == 0)
+ else if (weechat_strcasecmp (params[0], "req") == 0)
{
/* client is asking for one or more server capabilities */
num_caps_received = 0;
caps_ok = 0;
server_caps = RELAY_IRC_DATA(client, server_capabilities);
- for (i = 1; i < argc; i++)
+ for (i = 1; i < num_params; i++)
{
- ptr_cap = (argv[i][0] == ':') ? argv[i] + 1 : argv[i];
- if (ptr_cap[0])
+ num_caps_received++;
+ capability = relay_irc_search_server_capability (params[i]);
+ if (capability >= 0)
{
- num_caps_received++;
- capability = relay_irc_search_server_capability (ptr_cap);
- if (capability >= 0)
- {
- caps_ok = 1;
- server_caps |= 1 << capability;
- }
- else
- {
- caps_ok = 0;
- break;
- }
+ caps_ok = 1;
+ server_caps |= 1 << capability;
+ }
+ else
+ {
+ caps_ok = 0;
+ break;
}
}
if (caps_ok)
RELAY_IRC_DATA(client, server_capabilities) = server_caps;
+ str_caps = (num_params > 1) ?
+ weechat_string_rebuild_split_string (params, " ", 1, -1) : NULL;
relay_irc_sendf (
client,
":%s CAP %s %s :%s",
RELAY_IRC_DATA(client, address),
(RELAY_IRC_DATA(client, nick)) ? RELAY_IRC_DATA(client, nick) : "nick",
(caps_ok) ? "ACK" : "NAK",
- (argc >= 2) ? ((argv_eol[1][0] == ':') ? argv_eol[1] + 1 : argv_eol[1]) : "");
+ (str_caps) ? str_caps : "");
+ if (str_caps)
+ free (str_caps);
/*
* if the CAP REQ command is received without arguments, we consider
@@ -1308,7 +1311,7 @@ relay_irc_recv_command_capab (struct t_relay_client *client,
RELAY_IRC_DATA(client, cap_end_received) = 1;
}
}
- else if (weechat_strcasecmp (argv[0], "end") == 0)
+ else if (weechat_strcasecmp (params[0], "end") == 0)
{
if (!RELAY_IRC_DATA(client, connected))
RELAY_IRC_DATA(client, cap_end_received) = 1;
@@ -1322,19 +1325,17 @@ relay_irc_recv_command_capab (struct t_relay_client *client,
void
relay_irc_recv (struct t_relay_client *client, const char *data)
{
- char str_time[128], str_signal[128], str_server_channel[256], *nick;
- char *version, str_command[128], *target, **irc_argv, **irc_argv_eol;
- char *pos, *password, *irc_is_channel, *info;
- const char *irc_command, *irc_channel, *irc_args, *irc_args2;
- int irc_argc, redirect_msg;
- const char *isupport, *pos_password;
struct t_hashtable *hash_parsed, *hash_redirect;
struct t_infolist *infolist_server;
+ const char *irc_command, *str_num_params, *isupport, *pos_password;
+ 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;
+ long num_params;
+ int i, redirect_msg;
hash_parsed = NULL;
- irc_argv = NULL;
- irc_argv_eol = NULL;
- irc_argc = 0;
+ params = NULL;
/* display debug message */
if (weechat_relay_plugin->debug >= 2)
@@ -1352,29 +1353,23 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
if (!hash_parsed)
goto end;
irc_command = weechat_hashtable_get (hash_parsed, "command");
- irc_channel = weechat_hashtable_get (hash_parsed, "channel");
- irc_args = weechat_hashtable_get (hash_parsed, "arguments");
- if (irc_args)
+ str_num_params = weechat_hashtable_get (hash_parsed, "num_params");
+ error = NULL;
+ num_params = strtol (str_num_params, &error, 10);
+ if (!error || error[0])
+ num_params = 0;
+ if (num_params > 0)
{
- irc_argv = weechat_string_split (
- irc_args,
- " ",
- NULL,
- WEECHAT_STRING_SPLIT_STRIP_LEFT
- | WEECHAT_STRING_SPLIT_STRIP_RIGHT
- | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
- 0,
- &irc_argc);
- irc_argv_eol = weechat_string_split (
- irc_args,
- " ",
- NULL,
- WEECHAT_STRING_SPLIT_STRIP_LEFT
- | WEECHAT_STRING_SPLIT_STRIP_RIGHT
- | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS
- | WEECHAT_STRING_SPLIT_KEEP_EOL,
- 0,
- NULL);
+ params = malloc ((num_params + 1) * sizeof (params[0]));
+ if (params)
+ {
+ for (i = 0; i < num_params; i++)
+ {
+ snprintf (str_param, sizeof (str_param), "param%d", i + 1);
+ params[i] = weechat_hashtable_get (hash_parsed, str_param);
+ }
+ params[num_params] = NULL;
+ }
}
/*
@@ -1383,20 +1378,20 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
*/
if (irc_command && (weechat_strcasecmp (irc_command, "nick") == 0))
{
- if (irc_args && irc_args[0])
+ if (num_params > 0)
{
if (RELAY_IRC_DATA(client, nick))
free (RELAY_IRC_DATA(client, nick));
- RELAY_IRC_DATA(client, nick) = strdup (irc_args);
+ RELAY_IRC_DATA(client, nick) = strdup (params[0]);
}
}
/* server capabilities */
if (irc_command && (weechat_strcasecmp (irc_command, "cap") == 0))
{
- if (irc_argc > 0)
+ if (num_params > 0)
{
relay_irc_recv_command_capab (client,
- irc_argc, irc_argv, irc_argv_eol);
+ num_params, (const char **)params);
}
}
/* if client is not yet "connected" */
@@ -1404,24 +1399,25 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
{
if (irc_command && (weechat_strcasecmp (irc_command, "pass") == 0))
{
- if (irc_args && irc_args[0])
+ if (num_params > 0)
{
- pos_password = (irc_args[0] == ':') ? irc_args + 1 : irc_args;
+ pos_password = params[0];
if (!client->protocol_args)
{
pos = strchr (pos_password, ':');
if (pos)
{
- client->protocol_args = weechat_strndup (pos_password,
- pos - pos_password);
+ client->protocol_args = weechat_strndup (
+ pos_password, pos - pos_password);
relay_client_set_desc (client);
pos_password = pos + 1;
}
}
if (!RELAY_IRC_DATA(client, password_ok))
{
- password = weechat_string_eval_expression (weechat_config_string (relay_config_network_password),
- NULL, NULL, NULL);
+ password = weechat_string_eval_expression (
+ weechat_config_string (relay_config_network_password),
+ NULL, NULL, NULL);
if (password)
{
if (strcmp (password, pos_password) == 0)
@@ -1476,7 +1472,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
RELAY_STATUS_DISCONNECTED);
goto end;
}
- if (irc_args && irc_args[0])
+ if (num_params > 0)
{
RELAY_IRC_DATA(client, user_received) = 1;
}
@@ -1602,80 +1598,80 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
{
if (irc_command && weechat_strcasecmp (irc_command, "join") == 0)
{
+ str_args = weechat_string_rebuild_split_string (
+ (const char **)params, " ", 0, -1);
relay_irc_input_send (client, NULL,
"priority_high",
"/join %s",
- irc_args);
+ (str_args) ? str_args : "");
+ if (str_args)
+ free (str_args);
}
else if (irc_command && weechat_strcasecmp (irc_command, "part") == 0)
{
+ str_args = weechat_string_rebuild_split_string (
+ (const char **)params, " ", 0, -1);
relay_irc_input_send (client, NULL,
"priority_high",
"/part %s",
- irc_args);
+ (str_args) ? str_args : "");
+ if (str_args)
+ free (str_args);
}
else if (irc_command && weechat_strcasecmp (irc_command, "ping") == 0)
{
+ str_args = weechat_string_rebuild_split_string (
+ (const char **)params, " ", 0, -1);
relay_irc_sendf (client,
":%s PONG %s :%s",
RELAY_IRC_DATA(client, address),
RELAY_IRC_DATA(client, address),
- irc_args);
+ (str_args) ? str_args : "");
+ if (str_args)
+ free (str_args);
}
- else if (irc_command && irc_channel && irc_channel[0]
- && irc_args && irc_args[0]
- && (weechat_strcasecmp (irc_command, "notice") == 0))
+ else if (irc_command && (weechat_strcasecmp (irc_command, "notice") == 0))
{
- irc_args2 = strchr (irc_args, ' ');
- if (irc_args2)
+ if (num_params > 1)
{
- target = weechat_strndup (irc_args, irc_args2 - irc_args);
- if (target)
- {
- while (irc_args2[0] == ' ')
- {
- irc_args2++;
- }
- if (irc_args2[0] == ':')
- irc_args2++;
- relay_irc_input_send (client, NULL,
- "priority_high",
- "/notice %s %s",
- target, irc_args2);
- free (target);
- }
+ str_args = weechat_string_rebuild_split_string (
+ (const char **)params, " ", 1, -1);
+ relay_irc_input_send (client, NULL,
+ "priority_high",
+ "/notice %s %s",
+ params[0],
+ (str_args) ? str_args : "");
+ if (str_args)
+ free (str_args);
}
}
- else if (irc_command && irc_channel && irc_channel[0]
- && irc_args && irc_args[0]
- && (weechat_strcasecmp (irc_command, "privmsg") == 0))
+ else if (irc_command && (weechat_strcasecmp (irc_command, "privmsg") == 0))
{
- irc_args2 = strchr (irc_args, ' ');
- if (!irc_args2)
- irc_args2 = irc_args;
- while (irc_args2[0] == ' ')
- {
- irc_args2++;
- }
- if (irc_args2[0] == ':')
- irc_args2++;
- irc_is_channel = weechat_info_get ("irc_is_channel", irc_channel);
- if (irc_is_channel && (strcmp (irc_is_channel, "1") == 0))
- {
- relay_irc_input_send (client, irc_channel,
- "priority_high,user_message",
- "%s",
- irc_args2);
- }
- else
+ if (num_params > 1)
{
- relay_irc_input_send (client, NULL,
- "priority_high",
- "/query %s %s",
- irc_channel, irc_args2);
+ str_args = weechat_string_rebuild_split_string (
+ (const char **)params, " ", 1, -1);
+ 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 : "");
+ }
+ 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 (irc_is_channel)
- free (irc_is_channel);
}
else if (!relay_irc_command_ignored (irc_command))
{
@@ -1693,42 +1689,42 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
weechat_hashtable_set (hash_redirect, "signal", str_signal);
if (weechat_strcasecmp (irc_command, "mode") == 0)
{
- if (irc_argc > 0)
+ if (num_params > 0)
{
- if (irc_argc == 1)
+ if (num_params == 1)
redirect_msg = 1;
weechat_hashtable_set (hash_redirect, "pattern",
"mode_channel");
weechat_hashtable_set (hash_redirect, "string",
- irc_argv[0]);
+ params[0]);
snprintf (str_server_channel,
sizeof (str_server_channel),
"%s,%s",
client->protocol_args,
- irc_argv[0]);
+ params[0]);
info = weechat_info_get ("irc_is_channel",
str_server_channel);
if (info && (strcmp (info, "1") == 0))
{
/* command "MODE #channel ..." */
- if (irc_argc == 2)
+ if (num_params == 2)
{
- if ((strcmp (irc_argv[1], "b") == 0)
- || (strcmp (irc_argv[1], "+b") == 0))
+ if ((strcmp (params[1], "b") == 0)
+ || (strcmp (params[1], "+b") == 0))
{
redirect_msg = 1;
weechat_hashtable_set (hash_redirect, "pattern",
"mode_channel_ban");
}
- else if ((strcmp (irc_argv[1], "e") == 0)
- || (strcmp (irc_argv[1], "+e") == 0))
+ else if ((strcmp (params[1], "e") == 0)
+ || (strcmp (params[1], "+e") == 0))
{
redirect_msg = 1;
weechat_hashtable_set (hash_redirect, "pattern",
"mode_channel_ban_exception");
}
- else if ((strcmp (irc_argv[1], "I") == 0)
- || (strcmp (irc_argv[1], "+I") == 0))
+ else if ((strcmp (params[1], "I") == 0)
+ || (strcmp (params[1], "+I") == 0))
{
redirect_msg = 1;
weechat_hashtable_set (hash_redirect, "pattern",
@@ -1739,7 +1735,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
else
{
/* command "MODE nick ..." */
- if (irc_argc == 1)
+ if (num_params == 1)
{
redirect_msg = 1;
weechat_hashtable_set (hash_redirect, "pattern",
@@ -1766,7 +1762,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
|| (weechat_strcasecmp (irc_command, "whois") == 0)
|| (weechat_strcasecmp (irc_command, "whowas") == 0))
{
- if (irc_argc >= 1)
+ if (num_params > 0)
{
redirect_msg = 1;
snprintf (str_command, sizeof (str_command),
@@ -1775,7 +1771,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
weechat_hashtable_set (hash_redirect, "pattern",
str_command);
weechat_hashtable_set (hash_redirect, "string",
- irc_argv[0]);
+ params[0]);
}
}
else if (weechat_strcasecmp (irc_command, "time") == 0)
@@ -1810,10 +1806,8 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
end:
if (hash_parsed)
weechat_hashtable_free (hash_parsed);
- if (irc_argv)
- weechat_string_free_split (irc_argv);
- if (irc_argv_eol)
- weechat_string_free_split (irc_argv_eol);
+ if (params)
+ free (params);
}
/*