Committer  : entrope
CVSROOT    : /cvsroot/undernet-ircu
Module     : ircu2.10
Commit time: 2004-12-18 04:41:17 UTC

Modified files:
     ChangeLog include/channel.h ircd/channel.c ircd/m_silence.c

Log message:

Fix bugs and memory leaks in ban management.

---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.518 ircu2.10/ChangeLog:1.519
--- ircu2.10/ChangeLog:1.518    Fri Dec 17 14:41:02 2004
+++ ircu2.10/ChangeLog  Fri Dec 17 20:41:04 2004
@@ -1,5 +1,20 @@
 2004-12-17  Michael Poole <[EMAIL PROTECTED]>
 
+       * ircd/channel.h (apply_ban): Add new flag to indicate whether
+       newban should be free()'d after it is used.
+
+       * ircd/channel.c (apply_ban): Likewise.  Also set BAN_DEL flag
+       when setting BAN_OVERLAPPED, and free newban when BAN_DEL.
+       (mode_parse_ban): Delete buggy shortcut when channel banlist is
+       empty.
+       (mode_process_bans): Always give ownership of ban->banstr to the
+       mode buffer, avoiding a memory leak.
+
+       * ircd/m_silence.c (apply_silence): Pass new parameter to
+       apply_ban.
+
+2004-12-17  Michael Poole <[EMAIL PROTECTED]>
+
        * ircd/channel.c (sub1_from_channel): Immediately destroy
        non-Apass channels when oplevels are enabled; otherwise, they can
        stay opless for a considerable period.
Index: ircu2.10/include/channel.h
diff -u ircu2.10/include/channel.h:1.47 ircu2.10/include/channel.h:1.48
--- ircu2.10/include/channel.h:1.47     Sun Nov  7 11:29:14 2004
+++ ircu2.10/include/channel.h  Fri Dec 17 20:41:05 2004
@@ -19,7 +19,7 @@
  */
 /** @file
  * @brief Channel management and maintenance.
- * @version $Id: channel.h,v 1.47 2004/11/07 19:29:14 entrope Exp $
+ * @version $Id: channel.h,v 1.48 2004/12/18 04:41:05 entrope Exp $
  */
 #ifndef INCLUDED_channel_h
 #define INCLUDED_channel_h
@@ -456,7 +456,7 @@
 extern int joinbuf_flush(struct JoinBuf *jbuf);
 extern struct Ban *make_ban(const char *banstr);
 extern struct Ban *find_ban(struct Client *cptr, struct Ban *banlist);
-extern int apply_ban(struct Ban **banlist, struct Ban *newban);
+extern int apply_ban(struct Ban **banlist, struct Ban *newban, int free);
 extern void free_ban(struct Ban *ban);
 
 #endif /* INCLUDED_channel_h */
Index: ircu2.10/ircd/channel.c
diff -u ircu2.10/ircd/channel.c:1.112 ircu2.10/ircd/channel.c:1.113
--- ircu2.10/ircd/channel.c:1.112       Fri Dec 17 14:41:03 2004
+++ ircu2.10/ircd/channel.c     Fri Dec 17 20:41:06 2004
@@ -19,7 +19,7 @@
  */
 /** @file
  * @brief Channel management and maintanance
- * @version $Id: channel.c,v 1.112 2004/12/17 22:41:03 entrope Exp $
+ * @version $Id: channel.c,v 1.113 2004/12/18 04:41:06 entrope Exp $
  */
 #include "config.h"
 
@@ -2683,7 +2683,7 @@
  * @param[in] newban Ban (or exception) to add (or remove).
  * @return Zero if \a newban could be applied, non-zero if not.
  */
-int apply_ban(struct Ban **banlist, struct Ban *newban)
+int apply_ban(struct Ban **banlist, struct Ban *newban, int free)
 {
   struct Ban *ban;
   size_t count = 0;
@@ -2694,7 +2694,8 @@
     /* If a less specific entry is found, fail.  */
     for (ban = *banlist; ban; ban = ban->next) {
       if (!bmatch(ban, newban)) {
-        free_ban(newban);
+        if (free)
+          free_ban(newban);
         return 1;
       }
       if (!(ban->flags & (BAN_OVERLAPPED|BAN_DEL))) {
@@ -2705,7 +2706,7 @@
     /* Mark more specific entries and add this one to the end of the list. */
     while ((ban = *banlist) != NULL) {
       if (!bmatch(newban, ban)) {
-        ban->flags |= BAN_OVERLAPPED;
+        ban->flags |= BAN_OVERLAPPED | BAN_DEL;
       }
       banlist = &ban->next;
     }
@@ -2716,16 +2717,16 @@
     /* Mark more specific entries. */
     for (ban = *banlist; ban; ban = ban->next) {
       if (!bmatch(newban, ban)) {
-        ban->flags |= BAN_OVERLAPPED;
+        ban->flags |= BAN_OVERLAPPED | BAN_DEL;
         remove_count++;
       }
     }
-    /* If no matches were found, fail. */
-    if (!remove_count) {
+    if (free)
       free_ban(newban);
-      return 3;
-    }
-    return 0;
+    else
+      MyFree(newban->banstr);
+    /* If no matches were found, fail. */
+    return remove_count ? 0 : 3;
   }
   free_ban(newban);
   return 4;
@@ -2738,7 +2739,7 @@
 mode_parse_ban(struct ParseState *state, int *flag_p)
 {
   char *t_str, *s;
-  struct Ban *ban, *newban = 0;
+  struct Ban *ban, *newban;
 
   if (state->parc <= 0) { /* Not enough args, send ban list */
     if (MyUser(state->sptr) && !(state->done & DONE_BANLIST)) {
@@ -2772,12 +2773,6 @@
     return;
   }
 
-  if (!state->chptr->banlist) {
-    state->chptr->banlist = newban; /* add our ban with its flags */
-    state->done |= DONE_BANCLEAN;
-    return;
-  }
-
   /* Clear all ADD/DEL/OVERLAPPED flags from ban list. */
   if (!(state->done & DONE_BANCLEAN)) {
     for (ban = state->chptr->banlist; ban; ban = ban->next)
@@ -2794,7 +2789,7 @@
   set_ban_mask(newban, collapse(pretty_mask(t_str)));
   newban->who = cli_name(state->sptr);
   newban->when = TStime();
-  apply_ban(&state->chptr->banlist, newban);
+  apply_ban(&state->chptr->banlist, newban, 0);
 }
 
 /*
@@ -2829,8 +2824,7 @@
       continue;
     } else if (ban->flags & BAN_DEL) { /* Deleted a ban? */
       modebuf_mode_string(state->mbuf, MODE_DEL | MODE_BAN,
-                         ban->banstr,
-                         state->flags & MODE_PARSE_SET);
+                         ban->banstr, 1);
 
       if (state->flags & MODE_PARSE_SET) { /* Ok, make it take effect */
        if (prevban) /* clip it out of the list... */
@@ -2873,8 +2867,7 @@
        } else {
          /* add the ban to the buffer */
          modebuf_mode_string(state->mbuf, MODE_ADD | MODE_BAN,
-                             ban->banstr,
-                             !(state->flags & MODE_PARSE_SET));
+                             ban->banstr, 1);
 
          if (state->flags & MODE_PARSE_SET) { /* create a new ban */
            newban = make_ban(ban->banstr);
Index: ircu2.10/ircd/m_silence.c
diff -u ircu2.10/ircd/m_silence.c:1.8 ircu2.10/ircd/m_silence.c:1.9
--- ircu2.10/ircd/m_silence.c:1.8       Fri Dec 10 21:14:03 2004
+++ ircu2.10/ircd/m_silence.c   Fri Dec 17 20:41:07 2004
@@ -22,7 +22,7 @@
  */
 /** @file
  * @brief Handlers for SILENCE command.
- * @version $Id: m_silence.c,v 1.8 2004/12/11 05:14:03 klmitch Exp $
+ * @version $Id: m_silence.c,v 1.9 2004/12/18 04:41:07 entrope Exp $
  */
 
 #include "config.h"
@@ -86,7 +86,7 @@
   /* Make the silence, set flags, and apply it. */
   sile = make_ban(mask);
   sile->flags |= flags;
-  return apply_ban(&cli_user(sptr)->silence, sile) ? NULL : sile;
+  return apply_ban(&cli_user(sptr)->silence, sile, 1) ? NULL : sile;
 }
 
 /** Apply and send silence updates for a user.
----------------------- End of diff -----------------------

Reply via email to