summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--src/plugins/irc/irc-batch.c26
-rw-r--r--src/plugins/irc/irc-batch.h5
-rw-r--r--src/plugins/irc/irc-protocol.c3
-rw-r--r--src/plugins/irc/irc-tag.c156
-rw-r--r--src/plugins/irc/irc-tag.h2
-rw-r--r--tests/unit/plugins/irc/test-irc-batch.cpp44
-rw-r--r--tests/unit/plugins/irc/test-irc-protocol.cpp26
-rw-r--r--tests/unit/plugins/irc/test-irc-tag.cpp91
9 files changed, 327 insertions, 27 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index 930ae486f..a2d52a239 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -39,6 +39,7 @@ Bug fixes::
* irc: fix display of country code in message 344 received as whois geo info (issue #1736)
* irc: add missing "account-tag" in list of supported capabilities
* irc: add channel in "autojoin" server option only when the channel is actually joined (issue #1990)
+ * irc: add missing tags on multiline messages (issue #1987)
* script: fix cursor position after `/script list -i` or `/script list -il`
* script: fix buffer used by command `/script list -i|-il|-o|-ol`
diff --git a/src/plugins/irc/irc-batch.c b/src/plugins/irc/irc-batch.c
index 76ff79ba2..337c29a0d 100644
--- a/src/plugins/irc/irc-batch.c
+++ b/src/plugins/irc/irc-batch.c
@@ -110,7 +110,7 @@ irc_batch_add_to_list (struct t_irc_server *server, struct t_irc_batch *batch)
struct t_irc_batch *
irc_batch_start_batch (struct t_irc_server *server, const char *reference,
const char *parent_ref, const char *type,
- const char *parameters)
+ const char *parameters, struct t_hashtable *tags)
{
struct t_irc_batch *ptr_batch;
@@ -130,6 +130,7 @@ irc_batch_start_batch (struct t_irc_server *server, const char *reference,
ptr_batch->parent_ref = (parent_ref) ? strdup (parent_ref) : NULL;
ptr_batch->type = strdup (type);
ptr_batch->parameters = (parameters) ? strdup (parameters) : NULL;
+ ptr_batch->tags = (tags) ? weechat_hashtable_dup (tags) : NULL;
ptr_batch->start_time = time (NULL);
ptr_batch->messages = NULL;
ptr_batch->end_received = 0;
@@ -188,6 +189,8 @@ irc_batch_free (struct t_irc_server *server, struct t_irc_batch *batch)
free (batch->type);
if (batch->parameters)
free (batch->parameters);
+ if (batch->tags)
+ weechat_hashtable_free (batch->tags);
if (batch->messages)
weechat_string_dyn_free (batch->messages, 1);
@@ -226,7 +229,7 @@ irc_batch_process_messages (struct t_irc_server *server,
struct t_irc_batch *batch)
{
char **list_messages, *command, *channel, modifier_data[1024], *new_messages;
- char *message;
+ char *message, *message2;
int i, count_messages;
if (!batch || !batch->messages)
@@ -261,8 +264,13 @@ irc_batch_process_messages (struct t_irc_server *server,
if (!message)
continue;
+ message2 = irc_tag_add_tags_to_message (message,
+ batch->tags);
+ if (!message2)
+ continue;
+
irc_message_parse (server,
- message,
+ message2,
NULL, /* tags */
NULL, /* message_without_tags */
NULL, /* nick */
@@ -280,13 +288,13 @@ irc_batch_process_messages (struct t_irc_server *server,
NULL); /* pos_text */
/* add raw message */
- irc_raw_print (server, IRC_RAW_FLAG_RECV, message);
+ irc_raw_print (server, IRC_RAW_FLAG_RECV, message2);
/* call receive callback, ignoring batch tags */
- irc_protocol_recv_command (server, message, command, channel, 1);
+ irc_protocol_recv_command (server, message2, command, channel, 1);
- if (message)
- free (message);
+ free (message);
+ free (message2);
if (command)
free (command);
if (channel)
@@ -562,6 +570,10 @@ irc_batch_print_log (struct t_irc_server *server)
weechat_log_printf (" parent_ref. . . . . : '%s'", ptr_batch->parent_ref);
weechat_log_printf (" type. . . . . . . . : '%s'", ptr_batch->type);
weechat_log_printf (" parameters. . . . . : '%s'", ptr_batch->parameters);
+ weechat_log_printf (" tags. . . . . . . . : 0x%lx (hashtable: '%s')",
+ ptr_batch->tags,
+ weechat_hashtable_get_string (ptr_batch->tags,
+ "keys_values"));
weechat_log_printf (" start_time. . . . . : %lld", (long long)ptr_batch->start_time);
weechat_log_printf (" message . . . . . . : 0x%lx ('%s')",
ptr_batch->messages,
diff --git a/src/plugins/irc/irc-batch.h b/src/plugins/irc/irc-batch.h
index 04b718dad..4ecc1b995 100644
--- a/src/plugins/irc/irc-batch.h
+++ b/src/plugins/irc/irc-batch.h
@@ -22,6 +22,7 @@
#include <time.h>
+struct t_hashtable;
struct t_irc_server;
struct t_irc_batch
@@ -30,6 +31,7 @@ struct t_irc_batch
char *parent_ref; /* ref of parent batch (optional) */
char *type; /* type */
char *parameters; /* parameters */
+ struct t_hashtable *tags; /* batch message tags */
time_t start_time; /* start time (to auto-purge if */
/* batch end is not received) */
char **messages; /* messages separated by '\n' */
@@ -46,7 +48,8 @@ extern struct t_irc_batch *irc_batch_start_batch (struct t_irc_server *server,
const char *reference,
const char *parent_ref,
const char *type,
- const char *parameters);
+ const char *parameters,
+ struct t_hashtable *tags);
extern int irc_batch_add_message (struct t_irc_server *server,
const char *reference,
const char *irc_message);
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 1ff109e28..d5172cb29 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -688,7 +688,8 @@ IRC_PROTOCOL_CALLBACK(batch)
params[0] + 1, /* reference */
weechat_hashtable_get (tags, "batch"), /* parent ref */
params[1], /* type */
- str_params);
+ str_params,
+ tags);
if (str_params)
free (str_params);
}
diff --git a/src/plugins/irc/irc-tag.c b/src/plugins/irc/irc-tag.c
index f4eefb317..8dd184713 100644
--- a/src/plugins/irc/irc-tag.c
+++ b/src/plugins/irc/irc-tag.c
@@ -283,3 +283,159 @@ irc_tag_parse (const char *tags,
return num_tags;
}
+
+/*
+ * Adds tags to a dynamic string, separated by semicolons, with escaped
+ * tag values.
+ */
+
+void
+irc_tag_add_to_string_cb (void *data,
+ struct t_hashtable *hashtable,
+ const void *key,
+ const void *value)
+{
+ char **string, *escaped;
+
+ /* make C compiler happy */
+ (void) hashtable;
+
+ string = (char **)data;
+
+ if (*string[0])
+ weechat_string_dyn_concat (string, ";", -1);
+
+ weechat_string_dyn_concat (string, key, -1);
+
+ if (value)
+ {
+ weechat_string_dyn_concat (string, "=", -1);
+ escaped = irc_tag_escape_value ((const char *)value);
+ weechat_string_dyn_concat (string,
+ (escaped) ? escaped : (const char *)value,
+ -1);
+ if (escaped)
+ free (escaped);
+ }
+}
+
+/*
+ * Converts hashtable with tags to a string (tags and values are escaped).
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+irc_tag_hashtable_to_string (struct t_hashtable *tags)
+{
+ char **string;
+
+ if (!tags)
+ return NULL;
+
+ string = weechat_string_dyn_alloc (64);
+ if (!string)
+ return NULL;
+
+ weechat_hashtable_map (tags, &irc_tag_add_to_string_cb, string);
+
+ return weechat_string_dyn_free (string, 0);
+}
+
+/*
+ * Adds tags to another hashtable.
+ */
+
+void
+irc_tag_add_to_hashtable_cb (void *data,
+ struct t_hashtable *hashtable,
+ const void *key,
+ const void *value)
+{
+ /* make C compiler happy */
+ (void) hashtable;
+
+ if (!weechat_hashtable_has_key ((struct t_hashtable *)data, key))
+ weechat_hashtable_set ((struct t_hashtable *)data, key, value);
+}
+
+/*
+ * Adds tags to an IRC message.
+ * Existing tags in message are kept unchanged.
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+irc_tag_add_tags_to_message (const char *message, struct t_hashtable *tags)
+{
+ char *msg_str_tags, **result, *new_tags;
+ const char *pos_space, *ptr_message;
+ struct t_hashtable *msg_hash_tags;
+
+ if (!message)
+ return NULL;
+
+ if (!tags)
+ return strdup (message);
+
+ result = NULL;
+ msg_str_tags = NULL;
+ msg_hash_tags = NULL;
+ new_tags = NULL;
+
+ if (message[0] == '@')
+ {
+ pos_space = strchr (message, ' ');
+ if (!pos_space)
+ goto end;
+ msg_str_tags = weechat_strndup (message + 1, pos_space - message - 1);
+ ptr_message = pos_space + 1;
+ while (ptr_message[0] == ' ')
+ {
+ ptr_message++;
+ }
+ }
+ else
+ {
+ ptr_message = message;
+ }
+
+ msg_hash_tags = weechat_hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ if (!msg_hash_tags)
+ goto end;
+
+ if (msg_str_tags)
+ irc_tag_parse (msg_str_tags, msg_hash_tags, NULL);
+
+ weechat_hashtable_map (tags, &irc_tag_add_to_hashtable_cb, msg_hash_tags);
+
+ result = weechat_string_dyn_alloc (64);
+ if (!result)
+ goto end;
+
+ new_tags = irc_tag_hashtable_to_string (msg_hash_tags);
+ if (!new_tags)
+ goto end;
+
+ if (new_tags[0])
+ {
+ weechat_string_dyn_concat (result, "@", -1);
+ weechat_string_dyn_concat (result, new_tags, -1);
+ weechat_string_dyn_concat (result, " ", -1);
+ }
+ weechat_string_dyn_concat (result, ptr_message, -1);
+
+end:
+ if (msg_str_tags)
+ free (msg_str_tags);
+ if (msg_hash_tags)
+ weechat_hashtable_free (msg_hash_tags);
+ if (new_tags)
+ free (new_tags);
+
+ return (result) ? weechat_string_dyn_free (result, 0) : NULL;
+}
diff --git a/src/plugins/irc/irc-tag.h b/src/plugins/irc/irc-tag.h
index c363d3294..a62e069f9 100644
--- a/src/plugins/irc/irc-tag.h
+++ b/src/plugins/irc/irc-tag.h
@@ -30,5 +30,7 @@ extern char *irc_tag_modifier_cb (const void *pointer,
extern int irc_tag_parse (const char *tags,
struct t_hashtable *hashtable,
const char *prefix_key);
+extern char *irc_tag_add_tags_to_message (const char *message,
+ struct t_hashtable *tags);
#endif /* WEECHAT_PLUGIN_IRC_TAG_H */
diff --git a/tests/unit/plugins/irc/test-irc-batch.cpp b/tests/unit/plugins/irc/test-irc-batch.cpp
index 95687638e..774755430 100644
--- a/tests/unit/plugins/irc/test-irc-batch.cpp
+++ b/tests/unit/plugins/irc/test-irc-batch.cpp
@@ -26,6 +26,8 @@
extern "C"
{
#include <string.h>
+#include "src/core/wee-hashtable.h"
+#include "src/plugins/weechat-plugin.h"
#include "src/plugins/irc/irc-batch.h"
#include "src/plugins/irc/irc-server.h"
}
@@ -43,14 +45,23 @@ TEST(IrcBatch, Search)
{
struct t_irc_server *server;
struct t_irc_batch *batch1, *batch2;
+ struct t_hashtable *tags;
server = irc_server_alloc ("server");
CHECK(server);
- batch1 = irc_batch_start_batch (server, "ref1", "parent_ref", "type", "params");
+ tags = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ CHECK(tags);
+ hashtable_set (tags, "time", "2023-08-09T07:43:01.830Z");
+ hashtable_set (tags, "msgid", "icqfzy7zdbpix4gy8pvzuv49kw");
+
+ batch1 = irc_batch_start_batch (server, "ref1", "parent_ref", "type", "params", tags);
CHECK(batch1);
- batch2 = irc_batch_start_batch (server, "ref2", "parent_ref", "type", "params");
+ batch2 = irc_batch_start_batch (server, "ref2", "parent_ref", "type", "params", NULL);
CHECK(batch2);
POINTERS_EQUAL(NULL, irc_batch_search (NULL, NULL));
@@ -105,19 +116,29 @@ TEST(IrcBatch, StartBatch)
{
struct t_irc_server *server;
struct t_irc_batch *batch;
+ struct t_hashtable *tags;
server = irc_server_alloc ("server");
CHECK(server);
+ tags = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ CHECK(tags);
+ hashtable_set (tags, "time", "2023-08-09T07:43:01.830Z");
+ hashtable_set (tags, "msgid", "icqfzy7zdbpix4gy8pvzuv49kw");
+
POINTERS_EQUAL(NULL, server->batches);
- batch = irc_batch_start_batch (server, "ref", NULL, "type", NULL);
+ batch = irc_batch_start_batch (server, "ref", NULL, "type", NULL, NULL);
CHECK(batch);
POINTERS_EQUAL(batch, server->batches);
STRCMP_EQUAL("ref", batch->reference);
POINTERS_EQUAL(NULL, batch->parent_ref);
STRCMP_EQUAL("type", batch->type);
POINTERS_EQUAL(NULL, batch->parameters);
+ POINTERS_EQUAL(NULL, batch->tags);
CHECK(batch->start_time > 0);
POINTERS_EQUAL(NULL, batch->messages);
LONGS_EQUAL(0, batch->end_received);
@@ -126,13 +147,19 @@ TEST(IrcBatch, StartBatch)
POINTERS_EQUAL(NULL, server->batches);
- batch = irc_batch_start_batch (server, "ref", "parent_ref", "type", "params");
+ batch = irc_batch_start_batch (server, "ref", "parent_ref", "type", "params",
+ tags);
CHECK(batch);
POINTERS_EQUAL(batch, server->batches);
STRCMP_EQUAL("ref", batch->reference);
STRCMP_EQUAL("parent_ref", batch->parent_ref);
STRCMP_EQUAL("type", batch->type);
STRCMP_EQUAL("params", batch->parameters);
+ CHECK(batch->tags);
+ STRCMP_EQUAL("2023-08-09T07:43:01.830Z",
+ (const char *)hashtable_get (batch->tags, "time"));
+ STRCMP_EQUAL("icqfzy7zdbpix4gy8pvzuv49kw",
+ (const char *)hashtable_get (batch->tags, "msgid"));
CHECK(batch->start_time > 0);
POINTERS_EQUAL(NULL, batch->messages);
@@ -159,7 +186,8 @@ TEST(IrcBatch, AddMessage)
server = irc_server_alloc ("server");
CHECK(server);
- batch = irc_batch_start_batch (server, "ref", "parent_ref", "type", "params");
+ batch = irc_batch_start_batch (server, "ref", "parent_ref", "type", "params",
+ NULL);
CHECK(batch);
irc_batch_add_message (server, "ref", ":alice PRIVMSG #test: test1");
@@ -187,10 +215,12 @@ TEST(IrcBatch, FreeAll)
server = irc_server_alloc ("server");
CHECK(server);
- batch1 = irc_batch_start_batch (server, "ref1", "parent_ref", "type", "params");
+ batch1 = irc_batch_start_batch (server, "ref1", "parent_ref", "type", "params",
+ NULL);
CHECK(batch1);
- batch2 = irc_batch_start_batch (server, "ref2", "parent_ref", "type", "params");
+ batch2 = irc_batch_start_batch (server, "ref2", "parent_ref", "type", "params",
+ NULL);
CHECK(batch2);
POINTERS_EQUAL(batch1, server->batches);
diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp
index e455d1cd3..101aa14ec 100644
--- a/tests/unit/plugins/irc/test-irc-protocol.cpp
+++ b/tests/unit/plugins/irc/test-irc-protocol.cpp
@@ -1626,7 +1626,8 @@ TEST(IrcProtocolWithServer, batch_with_batch_cap)
POINTERS_EQUAL(NULL, irc_batch_search (ptr_server, "ref2"));
/* multiline */
- RECV(":server BATCH +ref draft/multiline #test");
+ RECV("@time=2023-08-09T07:43:01.830Z;msgid=icqfzy7zdbpix4gy8pvzuv49kw "
+ ":server BATCH +ref draft/multiline #test");
CHECK_NO_MSG;
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :line 1");
CHECK_NO_MSG;
@@ -1634,13 +1635,14 @@ TEST(IrcProtocolWithServer, batch_with_batch_cap)
CHECK_NO_MSG;
RECV(":server BATCH -ref");
CHECK_CHAN("bob", "line 1",
- "irc_privmsg,irc_tag_batch=ref,irc_batch_type_draft/multiline,"
- "notify_message,prefix_nick_248,nick_bob,"
- "host_user_b@host_b,log1");
+ "irc_privmsg,irc_tag_batch=ref,irc_tag_time=2023-08-09T07:43:01.830Z,"
+ "irc_tag_msgid=icqfzy7zdbpix4gy8pvzuv49kw,"
+ "irc_batch_type_draft/multiline,notify_message,prefix_nick_248,"
+ "nick_bob,host_user_b@host_b,log1");
CHECK_CHAN("bob", "line 2",
- "irc_privmsg,irc_tag_batch=ref,irc_batch_type_draft/multiline,"
- "notify_message,prefix_nick_248,nick_bob,"
- "host_user_b@host_b,log1");
+ "irc_privmsg,irc_tag_batch=ref,irc_tag_time=2023-08-09T07:43:01.830Z,"
+ "irc_tag_msgid=icqfzy7zdbpix4gy8pvzuv49kw,irc_batch_type_draft/multiline,"
+ "notify_message,prefix_nick_248,nick_bob,host_user_b@host_b,log1");
/* multiline with CTCP */
RECV(":server BATCH +ref draft/multiline #test");
@@ -1667,7 +1669,8 @@ TEST(IrcProtocolWithServer, batch_with_batch_cap)
irc_server_buffer_set_input_multiline (ptr_server, 1);
/* multiline */
- RECV(":server BATCH +ref draft/multiline #test");
+ RECV("@time=2023-08-09T07:43:01.830Z;msgid=icqfzy7zdbpix4gy8pvzuv49kw "
+ ":server BATCH +ref draft/multiline #test");
CHECK_NO_MSG;
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :line 1");
CHECK_NO_MSG;
@@ -1676,9 +1679,10 @@ TEST(IrcProtocolWithServer, batch_with_batch_cap)
RECV(":server BATCH -ref");
CHECK_CHAN("bob", "line 1\n"
"line 2",
- "irc_privmsg,irc_tag_batch=ref,irc_batch_type_draft/multiline,"
- "notify_message,prefix_nick_248,nick_bob,host_user_b@host_b,"
- "log1");
+ "irc_privmsg,irc_tag_batch=ref,irc_tag_time=2023-08-09T07:43:01.830Z,"
+ "irc_tag_msgid=icqfzy7zdbpix4gy8pvzuv49kw,"
+ "irc_batch_type_draft/multiline,notify_message,prefix_nick_248,"
+ "nick_bob,host_user_b@host_b,log1");
/* multiline with CTCP */
RECV(":server BATCH +ref draft/multiline #test");
diff --git a/tests/unit/plugins/irc/test-irc-tag.cpp b/tests/unit/plugins/irc/test-irc-tag.cpp
index a24afc0c8..b9993c8e1 100644
--- a/tests/unit/plugins/irc/test-irc-tag.cpp
+++ b/tests/unit/plugins/irc/test-irc-tag.cpp
@@ -21,6 +21,8 @@
#include "CppUTest/TestHarness.h"
+#include "tests/tests.h"
+
extern "C"
{
#include <stdio.h>
@@ -28,6 +30,8 @@ extern "C"
#include "src/core/wee-hook.h"
#include "src/plugins/irc/irc-tag.h"
#include "src/plugins/plugin.h"
+
+extern char *irc_tag_hashtable_to_string (struct t_hashtable *tags);
}
#define WEE_CHECK_ESCAPE_VALUE(__result, __string) \
@@ -161,3 +165,90 @@ TEST(IrcTag, Parse)
hashtable_free (hashtable);
}
+
+/*
+ * Tests functions:
+ * irc_tag_add_to_string_cb
+ * irc_tag_hashtable_to_string
+ */
+
+TEST(IrcTag, HashtableToString)
+{
+ char *str;
+ struct t_hashtable *tags;
+
+ POINTERS_EQUAL(NULL, irc_tag_hashtable_to_string (NULL));
+
+ tags = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ CHECK(tags);
+
+ WEE_TEST_STR("", irc_tag_hashtable_to_string (tags));
+
+ hashtable_set (tags, "time", "2023-08-09T07:43:01.830Z");
+ hashtable_set (tags, "msgid", "icqfzy7zdbpix4gy8pvzuv49kw");
+ hashtable_set (tags, "test", "value with spaces");
+
+ WEE_TEST_STR("time=2023-08-09T07:43:01.830Z;"
+ "msgid=icqfzy7zdbpix4gy8pvzuv49kw;"
+ "test=value\\swith\\sspaces",
+ irc_tag_hashtable_to_string (tags));
+
+ hashtable_free (tags);
+}
+
+/*
+ * Tests functions:
+ * irc_tag_add_to_hashtable_cb
+ * irc_tag_add_tags_to_message
+ */
+
+TEST(IrcTag, AddTagsToMessage)
+{
+ char *str;
+ struct t_hashtable *tags;
+
+ POINTERS_EQUAL(NULL, irc_tag_add_tags_to_message (NULL, NULL));
+
+ WEE_TEST_STR("", irc_tag_add_tags_to_message ("", NULL));
+ WEE_TEST_STR(":nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ ":nick!user@host PRIVMSG #test :hello", NULL));
+ WEE_TEST_STR("@tag1;tag2=value2 :nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ "@tag1;tag2=value2 :nick!user@host PRIVMSG #test :hello",
+ NULL));
+
+ tags = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+ CHECK(tags);
+
+ WEE_TEST_STR(":nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ ":nick!user@host PRIVMSG #test :hello", tags));
+ WEE_TEST_STR("@tag1;tag2=value2 :nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ "@tag1;tag2=value2 :nick!user@host PRIVMSG #test :hello",
+ tags));
+
+ hashtable_set (tags, "time", "2023-08-09T07:43:01.830Z");
+ hashtable_set (tags, "msgid", "icqfzy7zdbpix4gy8pvzuv49kw");
+ hashtable_set (tags, "test", "value with spaces");
+
+ WEE_TEST_STR("@time=2023-08-09T07:43:01.830Z;msgid=icqfzy7zdbpix4gy8pvzuv49kw;"
+ "test=value\\swith\\sspaces :nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ ":nick!user@host PRIVMSG #test :hello", tags));
+ WEE_TEST_STR("@tag1;tag2=value2;time=2023-08-09T07:43:01.830Z;"
+ "msgid=icqfzy7zdbpix4gy8pvzuv49kw;test=value\\swith\\sspaces "
+ ":nick!user@host PRIVMSG #test :hello",
+ irc_tag_add_tags_to_message (
+ "@tag1;tag2=value2 :nick!user@host PRIVMSG #test :hello",
+ tags));
+
+ hashtable_free (tags);
+}