]> jfr.im git - irc/weechat/weechat.git/commitdiff
irc: fix extract of isupport value when it is last in list and without value (closes...
authorSébastien Helleu <redacted>
Mon, 15 Aug 2022 16:14:03 +0000 (18:14 +0200)
committerSébastien Helleu <redacted>
Mon, 15 Aug 2022 16:14:03 +0000 (18:14 +0200)
ChangeLog.adoc
src/plugins/irc/irc-protocol.c
src/plugins/irc/irc-server.c
tests/unit/plugins/irc/test-irc-protocol.cpp
tests/unit/plugins/irc/test-irc-server.cpp

index ba1b9f1845e808f20840a4f1b90ab77248d1d00f..bdd3f1beef48b6985bb4ef762d0b73df4755907b 100644 (file)
@@ -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
index 5c1b314c250e51cfc76f00fa00d749922c2431ae..3724c1216264f5b512e657aee8254845aab81c05 100644 (file)
@@ -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)
index a0f8acfe3a2a3a4b408a050137baa82ba6326157..143d78d71a88e3c5efb7243d96e6835fb83d9dbd 100644 (file)
@@ -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 */
index 5e48bf5d8ddb1fc1a11a293df791fb5cf17dd2ed..8bb918c6cbce7a15f7926c8be1c24aad774b6aa3 100644 (file)
@@ -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);
 }
 
 /*
index 3932bf9e399119fc81b10151c934ef5a66a39562..cf60429c18ed769e0ebe9a98e4746c82a6e6f48f 100644 (file)
@@ -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);
 }
 
 /*