summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--src/plugins/irc/irc-protocol.c16
-rw-r--r--src/plugins/irc/irc-server.c67
-rw-r--r--tests/unit/plugins/irc/test-irc-protocol.cpp10
-rw-r--r--tests/unit/plugins/irc/test-irc-server.cpp72
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);
}
/*