Fwd: [PATCH] bug in channel key mode handling

Kevin Easton kevin at sylandro.com
Fri Jul 4 04:32:05 EDT 2008


Hi all,

I've found a bug in the handling of channel mode strings containing +k
and -k modes.  If a chanop sends a mode like:

MODE #chan +k-k x x

then hybrid sends out to the channel:

MODE #chan +k-k  *

ie - the key from the +k is missing, because when hybrid saw the -k it killed
the key from the channel struct.

Since this also affects the MODE / TMODE line that hybrid sends on to
other servers, mode lines can be constructed that will desync the
channel modes (at least, the ones that take an argument).

I have attached a patch that fixes this, by only showing the last of a
series of +k / -k modes (and the same for +l / -l - there's no bug in
that case, but just for consistency).

      - caf


----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

-------------- next part --------------
--- channel_mode.c.931	2008-07-04 17:01:22.939995541 +1000
+++ channel_mode.c	2008-07-04 17:08:35.555032292 +1000
@@ -1191,10 +1191,10 @@
 
     ircsprintf(lstr, "%d", limit);
 
-    /* if somebody sets MODE #channel +ll 1 2, accept latter --fl */
+    /* Reduce any set of +l / -l modes to the last one used. --caf */
     for (i = 0; i < mode_count; i++)
     {
-      if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
+      if (mode_changes[i].letter == c)
         mode_changes[i].letter = 0;
     }
 
@@ -1215,6 +1215,13 @@
 
     chptr->mode.limit = 0;
 
+    /* Reduce any set of +l / -l modes to the last one used. --caf */
+    for (i = 0; i < mode_count; i++)
+    {
+      if (mode_changes[i].letter == c)
+        mode_changes[i].letter = 0;
+    }
+
     mode_changes[mode_count].letter = c;
     mode_changes[mode_count].dir = MODE_DEL;
     mode_changes[mode_count].caps = 0;
@@ -1262,10 +1269,10 @@
     assert(key[0] != ' ');
     strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key));
 
-    /* if somebody does MODE #channel +kk a b, accept latter --fl */
+    /* Reduce any set of +k / -k modes to the last one used. --caf */
     for (i = 0; i < mode_count; i++)
     {
-      if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
+      if (mode_changes[i].letter == c)
         mode_changes[i].letter = 0;
     }
 
@@ -1287,6 +1294,16 @@
 
     chptr->mode.key[0] = '\0';
 
+    /* Reduce any set of +k / -k modes to the last one used.
+     * This is particularly important here, because we just cleared
+     * the key from the Channel struct, so any prior +k modes in this
+     * mode command will bugger up if we try to send them on.  --caf */
+    for (i = 0; i < mode_count; i++)
+    {
+      if (mode_changes[i].letter == c)
+        mode_changes[i].letter = 0;
+    }
+
     mode_changes[mode_count].letter = c;
     mode_changes[mode_count].dir = MODE_DEL;
     mode_changes[mode_count].caps = 0;


More information about the hybrid mailing list