diff options
-rw-r--r-- | ChangeLog.adoc | 1 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 16 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 67 | ||||
-rw-r--r-- | tests/unit/plugins/irc/test-irc-protocol.cpp | 10 | ||||
-rw-r--r-- | tests/unit/plugins/irc/test-irc-server.cpp | 72 |
5 files changed, 119 insertions, 47 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index ba1b9f184..bdd3f1bee 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -36,6 +36,7 @@ Bug fixes:: * irc: add missing tag "irc_numeric" in all numeric IRC commands (issue #1804) * irc: display an error message when using command /dcc without xfer plugin loaded * irc: display ACCOUNT and CHGHOST commands in private buffers + * irc: fix extract of isupport value when it is last in list and without value (issue #1807) * guile: fix function hdata_get_string * javascript: fix return of long value in functions infolist_time, hdata_long and hdata_time * php: fix function hdata_compare diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 5c1b314c2..3724c1216 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -3676,7 +3676,7 @@ IRC_PROTOCOL_CALLBACK(001) IRC_PROTOCOL_CALLBACK(005) { - char *str_info, *error, *isupport2, *pos_start; + char *str_info, *error, *isupport2; int i, arg_last, length_isupport, length, casemapping, utf8mapping; long value; @@ -3764,7 +3764,6 @@ IRC_PROTOCOL_CALLBACK(005) str_info = irc_protocol_string_params (params, 1, arg_last); if (str_info && str_info[0]) { - pos_start = NULL; length = strlen (str_info); if (server->isupport) { @@ -3777,20 +3776,13 @@ IRC_PROTOCOL_CALLBACK(005) if (isupport2) { server->isupport = isupport2; - pos_start = server->isupport + length_isupport; + strcat (server->isupport, " "); + strcat (server->isupport, str_info); } } else { - server->isupport = malloc (1 + length + 1); - if (server->isupport) - pos_start = server->isupport; - } - if (pos_start) - { - pos_start[0] = ' '; - memcpy (pos_start + 1, str_info, length); - pos_start[length + 1] = '\0'; + server->isupport = strdup (str_info); } } if (str_info) diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index a0f8acfe3..143d78d71 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -986,40 +986,51 @@ irc_server_get_alternate_nick (struct t_irc_server *server) const char * irc_server_get_isupport_value (struct t_irc_server *server, const char *feature) { - char feature2[64], *pos_feature, *pos_equal, *pos_space; - int length; + const char *ptr_string, *pos_space; + int length, length_feature; static char value[256]; - if (!server || !server->isupport || !feature) + if (!server || !server->isupport || !feature || !feature[0]) return NULL; - /* search feature with value */ - snprintf (feature2, sizeof (feature2), " %s=", feature); - pos_feature = strstr (server->isupport, feature2); - if (pos_feature) - { - /* feature found with value, return value */ - pos_feature++; - pos_equal = strchr (pos_feature, '='); - pos_space = strchr (pos_feature, ' '); - if (pos_space) - length = pos_space - pos_equal - 1; - else - length = strlen (pos_equal) + 1; - if (length > (int)sizeof (value) - 1) - length = (int)sizeof (value) - 1; - memcpy (value, pos_equal + 1, length); - value[length] = '\0'; - return value; - } + length_feature = strlen (feature); - /* search feature without value */ - feature2[strlen (feature2) - 1] = ' '; - pos_feature = strstr (server->isupport, feature2); - if (pos_feature) + ptr_string = server->isupport; + while (ptr_string && ptr_string[0]) { - value[0] = '\0'; - return value; + if (strncmp (ptr_string, feature, length_feature) == 0) + { + switch (ptr_string[length_feature]) + { + case '=': + /* feature found with value, return value */ + ptr_string += length_feature + 1; + pos_space = strchr (ptr_string, ' '); + if (pos_space) + length = pos_space - ptr_string; + else + length = strlen (ptr_string); + if (length > (int)sizeof (value) - 1) + length = (int)sizeof (value) - 1; + memcpy (value, ptr_string, length); + value[length] = '\0'; + return value; + case ' ': + case '\0': + /* feature found without value, return empty string */ + value[0] = '\0'; + return value; + } + } + /* find start of next item */ + pos_space = strchr (ptr_string, ' '); + if (!pos_space) + break; + ptr_string = pos_space + 1; + while (ptr_string[0] == ' ') + { + ptr_string++; + } } /* feature not found in isupport */ diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp index 5e48bf5d8..8bb918c6c 100644 --- a/tests/unit/plugins/irc/test-irc-protocol.cpp +++ b/tests/unit/plugins/irc/test-irc-protocol.cpp @@ -2155,8 +2155,7 @@ TEST(IrcProtocolWithServer, 005_full) STRCMP_EQUAL("#", ptr_server->chantypes); STRCMP_EQUAL("eIbq,k,flj,CFLMPQScgimnprstuz", ptr_server->chanmodes); LONGS_EQUAL(100, ptr_server->monitor); - CHECK(ptr_server->isupport[0] == ' '); - STRCMP_EQUAL(IRC_MSG_005, ptr_server->isupport + 1); + STRCMP_EQUAL(IRC_MSG_005, ptr_server->isupport); /* check that realloc of info is OK if we receive the message again */ RECV(":server 005 alice " IRC_MSG_005 " :are supported"); @@ -2171,8 +2170,7 @@ TEST(IrcProtocolWithServer, 005_full) STRCMP_EQUAL("#", ptr_server->chantypes); STRCMP_EQUAL("eIbq,k,flj,CFLMPQScgimnprstuz", ptr_server->chanmodes); LONGS_EQUAL(100, ptr_server->monitor); - CHECK(ptr_server->isupport[0] == ' '); - STRCMP_EQUAL(IRC_MSG_005 " " IRC_MSG_005, ptr_server->isupport + 1); + STRCMP_EQUAL(IRC_MSG_005 " " IRC_MSG_005, ptr_server->isupport); } /* @@ -2193,12 +2191,12 @@ TEST(IrcProtocolWithServer, 005_multiple_messages) CHECK_SRV("-- PREFIX=(ohv)@%+ are supported"); STRCMP_EQUAL("ohv", ptr_server->prefix_modes); STRCMP_EQUAL("@%+", ptr_server->prefix_chars); - STRCMP_EQUAL(" PREFIX=(ohv)@%+", ptr_server->isupport); + STRCMP_EQUAL("PREFIX=(ohv)@%+", ptr_server->isupport); RECV(":server 005 alice HOSTLEN=24 :are supported"); CHECK_SRV("-- HOSTLEN=24 are supported"); LONGS_EQUAL(24, ptr_server->host_max_length); - STRCMP_EQUAL(" PREFIX=(ohv)@%+ HOSTLEN=24", ptr_server->isupport); + STRCMP_EQUAL("PREFIX=(ohv)@%+ HOSTLEN=24", ptr_server->isupport); } /* diff --git a/tests/unit/plugins/irc/test-irc-server.cpp b/tests/unit/plugins/irc/test-irc-server.cpp index 3932bf9e3..cf60429c1 100644 --- a/tests/unit/plugins/irc/test-irc-server.cpp +++ b/tests/unit/plugins/irc/test-irc-server.cpp @@ -275,7 +275,77 @@ TEST(IrcServer, GetAlternateNick) TEST(IrcServer, GetIsupportValue) { - /* TODO: write tests */ + struct t_irc_server *server; + + server = irc_server_alloc ("test_clienttagdeny"); + CHECK(server); + + if (server->isupport) + free (server->isupport); + server->isupport = strdup (""); + + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, NULL)); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TEST")); + + if (server->isupport) + free (server->isupport); + server->isupport = strdup ("AWAYLEN=307 BOT=B CASEMAPPING=ascii " + "CHANLIMIT=#:10 EMPTY= INVEX KICKLEN=307 WHOX"); + + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, NULL)); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "xxx")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "AWAYLE")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "WHO")); + + STRCMP_EQUAL("307", irc_server_get_isupport_value (server, "AWAYLEN")); + STRCMP_EQUAL("B", irc_server_get_isupport_value (server, "BOT")); + STRCMP_EQUAL("ascii", irc_server_get_isupport_value (server, "CASEMAPPING")); + STRCMP_EQUAL("#:10", irc_server_get_isupport_value (server, "CHANLIMIT")); + STRCMP_EQUAL("", irc_server_get_isupport_value (server, "EMPTY")); + STRCMP_EQUAL("", irc_server_get_isupport_value (server, "INVEX")); + STRCMP_EQUAL("307", irc_server_get_isupport_value (server, "KICKLEN")); + STRCMP_EQUAL("", irc_server_get_isupport_value (server, "WHOX")); + + if (server->isupport) + free (server->isupport); + server->isupport = strdup ("TEST SECOND"); + + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "T")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TES")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "EST")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TESTT")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "SEC")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "COND")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "SECONDD")); + + STRCMP_EQUAL("", irc_server_get_isupport_value (server, "TEST")); + STRCMP_EQUAL("", irc_server_get_isupport_value (server, "SECOND")); + + if (server->isupport) + free (server->isupport); + server->isupport = strdup ("TEST=abc"); + + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "T")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TES")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "EST")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TESTT")); + + STRCMP_EQUAL("abc", irc_server_get_isupport_value (server, "TEST")); + + if (server->isupport) + free (server->isupport); + server->isupport = strdup (" TEST=abc "); + + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "T")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TES")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "EST")); + POINTERS_EQUAL(NULL, irc_server_get_isupport_value (server, "TESTT")); + + STRCMP_EQUAL("abc", irc_server_get_isupport_value (server, "TEST")); + + irc_server_free (server); } /* |