diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2024-01-22 13:18:25 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2024-01-22 13:18:25 +0100 |
commit | 06b4e469772dee23229e5596394b1bff8de3ee4c (patch) | |
tree | 21a2524d3b840bcdbc1a056a0cb11c9dcbf8e8c3 | |
parent | 750e677490cd78fa4171614a59da30df0cf8a63c (diff) | |
download | weechat-06b4e469772dee23229e5596394b1bff8de3ee4c.zip |
irc: fix random date displayed when a received message contains tags but no "time" (closes #2064)
-rw-r--r-- | ChangeLog.adoc | 7 | ||||
-rw-r--r-- | ReleaseNotes.adoc | 5 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 16 | ||||
-rw-r--r-- | tests/tests-record.cpp | 16 | ||||
-rw-r--r-- | tests/tests-record.h | 4 | ||||
-rw-r--r-- | tests/unit/core/test-core-command.cpp | 12 | ||||
-rw-r--r-- | tests/unit/plugins/irc/test-irc-protocol.cpp | 136 |
7 files changed, 159 insertions, 37 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 11d75695f..6e3989ba8 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -10,6 +10,13 @@ This document lists all the changes for each version. + For a list of important changes that require manual actions, please look at release notes. +[[v4.3.0]] +== Version 4.3.0 (under dev) + +Bug fixes:: + + * irc: fix random date displayed when a received message contains tags but no "time" (issue #2064) + [[v4.2.0]] == Version 4.2.0 (2024-01-21) diff --git a/ReleaseNotes.adoc b/ReleaseNotes.adoc index 3431a5959..8f75f8e67 100644 --- a/ReleaseNotes.adoc +++ b/ReleaseNotes.adoc @@ -11,6 +11,11 @@ It is recommended to read it when upgrading to a new stable version. + For a complete list of changes, please look at ChangeLog. +[[v4.3.0]] +== Version 4.3.0 (under dev) + +No release notes. + [[v4.2.0]] == Version 4.2.0 (2024-01-21) diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index d18dca6e3..2d286d144 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -8085,7 +8085,7 @@ irc_protocol_recv_command (struct t_irc_server *server, char *message_colors_decoded, *pos_space, *tags; struct t_irc_channel *ptr_channel; t_irc_recv_func *cmd_recv_func; - const char *ptr_msg_after_tags, *ptr_batch_ref; + const char *ptr_msg_after_tags, *ptr_batch_ref, *ptr_tag_time; const char *nick1, *address1, *host1; char *address, *host, *host_no_color; struct t_irc_protocol_ctxt ctxt; @@ -8308,11 +8308,15 @@ irc_protocol_recv_command (struct t_irc_server *server, if (ctxt.tags) { irc_tag_parse (tags, ctxt.tags, NULL); - weechat_util_parse_time ( - weechat_hashtable_get (ctxt.tags, "time"), - &tv); - ctxt.date = tv.tv_sec; - ctxt.date_usec = tv.tv_usec; + ptr_tag_time = weechat_hashtable_get (ctxt.tags, "time"); + if (ptr_tag_time) + { + if (weechat_util_parse_time (ptr_tag_time, &tv)) + { + ctxt.date = tv.tv_sec; + ctxt.date_usec = tv.tv_usec; + } + } } free (tags); } diff --git a/tests/tests-record.cpp b/tests/tests-record.cpp index c1ccff4bc..8de870ca4 100644 --- a/tests/tests-record.cpp +++ b/tests/tests-record.cpp @@ -173,19 +173,17 @@ record_match (struct t_hashtable *recorded_msg, /* * Searches if a prefix/message has been displayed in a buffer. * - * Returns index of message displayed (≥ 0), -1 if message has NOT been - * displayed. + * Returns pointer to hashtable with the message found, NULL if the message + * has NOT been displayed. */ -int +struct t_hashtable * record_search (const char *buffer, const char *prefix, const char *message, const char *tags) { - int i, rc, size; + int i, size; struct t_hashtable *rec_msg; - rc = -1; - size = arraylist_size (recorded_messages); for (i = 0; i < size; i++) @@ -198,12 +196,12 @@ record_search (const char *buffer, const char *prefix, const char *message, && record_match (rec_msg, "message_no_color", message) && (!tags || !tags[0] || record_match (rec_msg, "tags", tags))) { - rc = i; - break; + return rec_msg; } } - return rc; + /* message not displayed */ + return NULL; } /* diff --git a/tests/tests-record.h b/tests/tests-record.h index 26da4fbab..29acaeac7 100644 --- a/tests/tests-record.h +++ b/tests/tests-record.h @@ -24,8 +24,8 @@ extern struct t_arraylist *recorded_messages; extern void record_start (); extern void record_stop (); -extern int record_search (const char *buffer, const char *prefix, - const char *message, const char *tags); +extern struct t_hashtable *record_search (const char *buffer, const char *prefix, + const char *message, const char *tags); extern void record_dump (char **msg); extern void record_error_missing (const char *message); diff --git a/tests/unit/core/test-core-command.cpp b/tests/unit/core/test-core-command.cpp index 0a510c8c5..deac8fc7a 100644 --- a/tests/unit/core/test-core-command.cpp +++ b/tests/unit/core/test-core-command.cpp @@ -43,7 +43,7 @@ extern "C" command_record ("core.weechat", __command); #define WEE_CHECK_MSG_BUFFER(__buffer_name, __prefix, __message) \ - if (record_search (__buffer_name, __prefix, __message, NULL) < 0) \ + if (!record_search (__buffer_name, __prefix, __message, NULL)) \ { \ char **msg = command_build_error (__buffer_name, __prefix, \ __message); \ @@ -53,8 +53,6 @@ extern "C" #define WEE_CHECK_MSG_CORE(__prefix, __message) \ WEE_CHECK_MSG_BUFFER("core.weechat", __prefix, __message); -#define WEE_SEARCH_MSG_CORE(__prefix, __message) \ - record_search ("core.weechat", __prefix, __message, NULL) TEST_GROUP(CoreCommand) @@ -380,10 +378,10 @@ TEST(CoreCommand, Reload) { WEE_CMD_CORE("/save"); WEE_CMD_CORE("/reload"); - LONGS_EQUAL(0, WEE_SEARCH_MSG_CORE("", "Options reloaded from sec.conf")); - LONGS_EQUAL(1, WEE_SEARCH_MSG_CORE("", "Options reloaded from weechat.conf")); - LONGS_EQUAL(2, WEE_SEARCH_MSG_CORE("", "Options reloaded from plugins.conf")); - LONGS_EQUAL(3, WEE_SEARCH_MSG_CORE("", "Options reloaded from charset.conf")); + WEE_CHECK_MSG_CORE("", "Options reloaded from sec.conf"); + WEE_CHECK_MSG_CORE("", "Options reloaded from weechat.conf"); + WEE_CHECK_MSG_CORE("", "Options reloaded from plugins.conf"); + WEE_CHECK_MSG_CORE("", "Options reloaded from charset.conf"); } /* diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp index 94d306439..dff8d0620 100644 --- a/tests/unit/plugins/irc/test-irc-protocol.cpp +++ b/tests/unit/plugins/irc/test-irc-protocol.cpp @@ -29,6 +29,7 @@ extern "C" #include <stdio.h> #include <string.h> #include <time.h> +#include <sys/time.h> #include "src/core/wee-arraylist.h" #include "src/core/wee-config-file.h" #include "src/core/wee-hashtable.h" @@ -99,7 +100,7 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities, server_recv (__irc_msg); #define CHECK_CORE(__prefix, __message) \ - if (record_search ("core.weechat", __prefix, __message, NULL) < 0) \ + if (!record_search ("core.weechat", __prefix, __message, NULL)) \ { \ char **msg = build_error ( \ "Core message not displayed", \ @@ -112,8 +113,8 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities, } #define CHECK_SRV(__prefix, __message, __tags) \ - if (record_search ("irc.server." IRC_FAKE_SERVER, __prefix, \ - __message, __tags) < 0) \ + if (!record_search ("irc.server." IRC_FAKE_SERVER, __prefix, \ + __message, __tags)) \ { \ char **msg = build_error ( \ "Server message not displayed", \ @@ -144,8 +145,8 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities, ""); #define CHECK_CHAN(__prefix, __message, __tags) \ - if (record_search ("irc." IRC_FAKE_SERVER ".#test", __prefix, \ - __message, __tags) < 0) \ + if (!record_search ("irc." IRC_FAKE_SERVER ".#test", __prefix, \ + __message, __tags)) \ { \ char **msg = build_error ( \ "Channel message not displayed", \ @@ -157,9 +158,72 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities, FAIL(string_dyn_free (msg, 0)); \ } +#define CHECK_CHAN_DATE_VALUE(__prefix, __message, __tags, \ + __date_sec, __date_usec) \ + { \ + struct timeval tv_now; \ + const char *ptr_date; \ + long value; \ + char *error; \ + gettimeofday (&tv_now, NULL); \ + struct t_hashtable *record = record_search ( \ + "irc." IRC_FAKE_SERVER ".#test", \ + __prefix, __message, __tags); \ + if (!record) \ + { \ + char **msg = build_error ( \ + "Channel message not displayed", \ + __prefix, \ + __message, \ + __tags, \ + "All messages displayed"); \ + record_dump (msg); \ + FAIL(string_dyn_free (msg, 0)); \ + } \ + ptr_date = (const char *)hashtable_get (record, "date"); \ + CHECK(ptr_date); \ + value = strtol (ptr_date, &error, 10); \ + CHECK(error && !error[0]); \ + LONGS_EQUAL(__date_sec, value); \ + ptr_date = (const char *)hashtable_get (record, "date_usec"); \ + CHECK(ptr_date); \ + value = strtol (ptr_date, &error, 10); \ + CHECK(error && !error[0]); \ + LONGS_EQUAL(__date_usec, value); \ + } + +#define CHECK_CHAN_DATE_NOW(__prefix, __message, __tags) \ + { \ + struct timeval tv_now; \ + const char *ptr_date; \ + long value; \ + char *error; \ + gettimeofday (&tv_now, NULL); \ + struct t_hashtable *record = record_search ( \ + "irc." IRC_FAKE_SERVER ".#test", \ + __prefix, __message, __tags); \ + if (!record) \ + { \ + char **msg = build_error ( \ + "Channel message not displayed", \ + __prefix, \ + __message, \ + __tags, \ + "All messages displayed"); \ + record_dump (msg); \ + FAIL(string_dyn_free (msg, 0)); \ + } \ + ptr_date = (const char *)hashtable_get (record, "date"); \ + CHECK(ptr_date); \ + value = strtol (ptr_date, &error, 10); \ + CHECK(error && !error[0]); \ + CHECK(value >= tv_now.tv_sec - 5); \ + CHECK(value <= tv_now.tv_sec + 5); \ + } + #define CHECK_PV(__nick, __prefix, __message, __tags) \ - if (record_search ("irc." IRC_FAKE_SERVER "." __nick, \ - __prefix, __message, __tags) < 0) \ + if (!record_search ("irc." IRC_FAKE_SERVER "." __nick, \ + __prefix, __message, __tags)) \ { \ char **msg = build_error ( \ "Private message not displayed", \ @@ -2802,9 +2866,9 @@ TEST(IrcProtocolWithServer, privmsg) /* message to channel/user */ RECV(":bob!user@host PRIVMSG #test :this is the message "); - CHECK_CHAN("bob", "this is the message ", - "irc_privmsg,notify_message,prefix_nick_248,nick_bob," - "host_user@host,log1"); + CHECK_CHAN_DATE_NOW("bob", "this is the message ", + "irc_privmsg,notify_message,prefix_nick_248,nick_bob," + "host_user@host,log1"); RECV(":bob!user@host PRIVMSG alice :this is the message "); CHECK_PV_CLOSE("bob", "bob", "this is the message ", "irc_privmsg,notify_private,prefix_nick_248,nick_bob," @@ -2813,15 +2877,61 @@ TEST(IrcProtocolWithServer, privmsg) /* message with tags to channel/user */ RECV("@tag1=value1;tag2=value2 :bob!user@host PRIVMSG #test " ":this is the message "); - CHECK_CHAN("bob", "this is the message ", - "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," - "notify_message,prefix_nick_248,nick_bob,host_user@host,log1"); + CHECK_CHAN_DATE_NOW("bob", "this is the message ", + "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," + "notify_message,prefix_nick_248,nick_bob,host_user@host,log1"); RECV("@tag1=value1;tag2=value2 :bob!user@host PRIVMSG alice " ":this is the message "); CHECK_PV_CLOSE("bob", "bob", "this is the message ", "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," "notify_private,prefix_nick_248,nick_bob,host_user@host,log1"); + /* message with tags + time as timestamp to channel/user */ + RECV("@tag1=value1;tag2=value2;time=1703500149 :bob!user@host PRIVMSG #test " + ":this is the message "); + CHECK_CHAN_DATE_VALUE( + "bob", + "this is the message ", + "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," + "irc_tag_time=1703500149,notify_message,prefix_nick_248,nick_bob," + "host_user@host,log1", + 1703500149, 0); + + /* message with tags + time as timestamp with milliseconds to channel/user */ + RECV("@tag1=value1;tag2=value2;time=1703500149.456 :bob!user@host PRIVMSG #test " + ":this is the message "); + CHECK_CHAN_DATE_VALUE( + "bob", + "this is the message ", + "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," + "irc_tag_time=1703500149.456,notify_message,prefix_nick_248,nick_bob," + "host_user@host,log1", + 1703500149, 456000); + + /* message with tags + time as timestamp with microseconds to channel/user */ + RECV("@tag1=value1;tag2=value2;time=1703500149.456789 :bob!user@host PRIVMSG #test " + ":this is the message "); + CHECK_CHAN_DATE_VALUE( + "bob", + "this is the message ", + "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," + "irc_tag_time=1703500149.456789,notify_message,prefix_nick_248,nick_bob," + "host_user@host,log1", + 1703500149, 456789); + + /* message with tags + time as ISO 8601 with microseconds to channel/user */ + RECV("@tag1=value1;tag2=value2;time=2023-12-25T10:29:09.456789Z " + ":bob!user@host PRIVMSG #test :this is the message "); + CHECK_CHAN_DATE_VALUE( + "bob", + "this is the message ", + "irc_privmsg,irc_tag_tag1=value1,irc_tag_tag2=value2," + "irc_tag_time=2023-12-25T10:29:09.456789Z,notify_message," + "prefix_nick_248,nick_bob," + "host_user@host,log1", + 1703500149, 456789); + + /* * message to channel/user from self nick * (case of bouncer or if echo-message capability is enabled) |