From 283c9d7ccffbcae0eee8fb3693597973b2fca55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sun, 14 May 2023 14:09:49 +0200 Subject: [PATCH] irc: do not allow send of empty messages (single line or multiline) --- src/plugins/irc/irc-message.c | 46 ++++++++++++++++++--- src/plugins/irc/irc-message.h | 1 + tests/unit/plugins/irc/test-irc-message.cpp | 24 +++++++++++ 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c index 0be7cb1d6..c6fdae08b 100644 --- a/src/plugins/irc/irc-message.c +++ b/src/plugins/irc/irc-message.c @@ -637,6 +637,34 @@ irc_message_parse_cap_multiline_value (struct t_irc_server *server, weechat_hashtable_free (values); } +/* + * Checks if a message is empty: either empty string or contains only newlines. + * + * Returns: + * 1: message is empty + * 0: message is NOT empty + */ + +int +irc_message_is_empty (const char *message) +{ + const char *ptr_msg; + + if (!message || !message[0]) + return 1; + + ptr_msg = message; + while (ptr_msg && ptr_msg[0]) + { + if (ptr_msg[0] != '\n') + return 0; + ptr_msg = weechat_utf8_next_char (ptr_msg); + } + + /* only newlines => consider message is empty */ + return 1; +} + /* * Encodes/decodes an IRC message using a charset. * @@ -1309,6 +1337,10 @@ irc_message_split_privmsg_notice (struct t_irc_message_split_context *context, rc = 1; + /* privmsg/notice with empty message: not allowed */ + if (irc_message_is_empty (arguments)) + return 1; + if (multiline) { index_multiline_args = 1; @@ -1499,15 +1531,17 @@ irc_message_split (struct t_irc_server *server, const char *message) struct t_irc_message_split_context split_context; char **argv, **argv_eol, *tags, *host, *command, *arguments, target[4096]; char *pos, monitor_action[3]; - int split_ok, argc, index_args, max_length_nick, max_length_user; - int max_length_host, max_length_nick_user_host, split_msg_max_length; - int multiline, multiline_max_bytes, multiline_max_lines; + int split_ok, split_privmsg, argc, index_args, max_length_nick; + int max_length_user, max_length_host, max_length_nick_user_host; + int split_msg_max_length, multiline, multiline_max_bytes; + int multiline_max_lines; split_context.hashtable = NULL; split_context.number = 1; split_context.total_bytes = 0; split_ok = 0; + split_privmsg = 0; tags = NULL; host = NULL; command = NULL; @@ -1679,6 +1713,7 @@ irc_message_split (struct t_irc_server *server, const char *message) * PRIVMSG target :some text here * NOTICE target :some text here */ + split_privmsg = 1; if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_privmsg_notice ( @@ -1738,8 +1773,9 @@ irc_message_split (struct t_irc_server *server, const char *message) end: if (!split_ok - || (weechat_hashtable_get_integer (split_context.hashtable, - "items_count") == 0)) + || (!split_privmsg + && (weechat_hashtable_get_integer (split_context.hashtable, + "items_count") == 0))) { split_context.number = (message) ? 1 : 0; irc_message_split_add (&split_context, diff --git a/src/plugins/irc/irc-message.h b/src/plugins/irc/irc-message.h index 6583ff44a..b0670fba5 100644 --- a/src/plugins/irc/irc-message.h +++ b/src/plugins/irc/irc-message.h @@ -46,6 +46,7 @@ extern struct t_hashtable *irc_message_parse_to_hashtable (struct t_irc_server * extern struct t_hashtable *irc_message_parse_cap_value (const char *value); extern void irc_message_parse_cap_multiline_value (struct t_irc_server *server, const char *value); +extern int irc_message_is_empty (const char *message); extern char *irc_message_convert_charset (const char *message, int pos_start, const char *modifier, diff --git a/tests/unit/plugins/irc/test-irc-message.cpp b/tests/unit/plugins/irc/test-irc-message.cpp index 39a232c5a..3939060e9 100644 --- a/tests/unit/plugins/irc/test-irc-message.cpp +++ b/tests/unit/plugins/irc/test-irc-message.cpp @@ -946,6 +946,24 @@ convert_irc_charset_cb (const void *pointer, void *data, return new_string; } +/* + * Tests functions: + * irc_message_is_empty + */ + +TEST(IrcMessage, IsEmpty) +{ + LONGS_EQUAL(1, irc_message_is_empty (NULL)); + LONGS_EQUAL(1, irc_message_is_empty ("")); + LONGS_EQUAL(1, irc_message_is_empty ("\n")); + LONGS_EQUAL(1, irc_message_is_empty ("\n\n\n\n\n\n\n\n")); + + LONGS_EQUAL(0, irc_message_is_empty (" ")); + LONGS_EQUAL(0, irc_message_is_empty ("\n ")); + LONGS_EQUAL(0, irc_message_is_empty ("\n \n")); + LONGS_EQUAL(0, irc_message_is_empty ("test")); +} + /* * Tests functions: * irc_message_convert_charset @@ -1516,6 +1534,12 @@ TEST(IrcMessage, Split) (const char *)hashtable_get (hashtable, "msg1")); hashtable_free (hashtable); + /* PRIVMSG with no content: no split (not allowed) */ + hashtable = irc_message_split (server, "PRIVMSG #channel :"); + CHECK(hashtable); + LONGS_EQUAL(0, hashtable->items_count); + hashtable_free (hashtable); + /* PRIVMSG with small content: no split */ hashtable = irc_message_split (server, "PRIVMSG #channel :test"); CHECK(hashtable);