Răsfoiți Sursa

Merge branch 'master' into 39-dynamic-roles

* master:
  Reduce diff with upstream and only clear some things once.
  Limit where cookies_disabled is reset
  Fix memory leak in alias loop detection.
  Fix memory leak with rejected channel auth commands
  Remove NULL frees handled by clear_channel above.
  Remove redundant sets (handled by calloc)
  Don't truncate bot's join time on .reset
  Pass known memberlist pointer to check_this_member
  On a nick change, clear any pending modes, but still check for actions on the new nick!uhost.
  Remove bogus comment
Bryan Drewery 10 ani în urmă
părinte
comite
9673ad15c8

+ 3 - 0
doc/UPDATES.md

@@ -22,6 +22,9 @@
   * Fix bot not auto-opping after just connecting.
   * Fix invites not being applied in -dynamicinvites channels when +i is set.
   * Fix not handling auto-op in minutely channel rechecks.
+  * Fix auto-voice and auto-op not applying after a nick change.
+  * Don't truncate bot's join time on .reset.
+  * Fix various small memory leaks.
 
 # 1.4.6
   * Disable demo TCL support by default to prevent confusion during build.

+ 9 - 11
src/core_binds.cc

@@ -85,8 +85,8 @@ bool check_aliases(int idx, const char *cmd, const char *args)
       /* Simple loop check */
       if (!strcasecmp(cmd, p)) {
         putlog(LOG_WARN, "*", "Loop detected in alias '%s'", p);
-        if (argsp)
-          free(argsp);
+        free(aliasp);
+        free(argsp);
         return 0;
       }
 
@@ -103,16 +103,14 @@ bool check_aliases(int idx, const char *cmd, const char *args)
       if (!find) {
         /* Does the cmd exist though? (Hub-only cmd from a leaf or a leaf-only cmd from a hub, or restricted cmd) */
         if (findcmd(cmd, 0)) {
-          if (argsp)
-            free(argsp);
+          free(argsp);
           free(aliasp);
           return 0; /* Show bad cmd */
         } else {
           /* nope, show alias error */
           dprintf(idx, "'%s' is an invalid alias: references alias '%s'.\n", cmd, p);
           putlog(LOG_ERROR, "*", "Invalid alias '%s' attempted: references alias '%s'.", cmd, p);
-          if (argsp)
-            free(argsp);
+          free(argsp);
           free(aliasp);
           return 1; /* Alias was found -- just not accepted */
         }
@@ -154,15 +152,13 @@ bool check_aliases(int idx, const char *cmd, const char *args)
         putlog(LOG_CMDS, "*", "@ #%s# [%s -> %s] ...", dcc[idx].nick, cmd, p);
       check_bind_dcc(p, idx, myargs);
 
-      if (myargs)
-        free(myargs);
+      free(myargs);
       break;
     }
   }
 
   free(aliasp);
-  if (argsp)
-    free(argsp);
+  free(argsp);
 
   return found;
 }
@@ -233,8 +229,10 @@ int real_check_bind_dcc(const char *cmd, int idx, const char *text, Auth *auth)
   }
 
   if (entry && auth) {
-    if (!(entry->cflags & AUTH))
+    if (!(entry->cflags & AUTH)) {
+      free(args);
       return 0;
+    }
   }
 
   hits = 0;

+ 0 - 9
src/mod/channels.mod/chanmisc.cc

@@ -1165,15 +1165,6 @@ int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan->ban_time = global_ban_time;
     chan->exempt_time = global_exempt_time;
     chan->invite_time = global_invite_time;
-    chan->channel.jointime = 0;
-    chan->channel.parttime = 0;
-    chan->channel.fighting = 0;
-    chan->channel.drone_set_mode = 0;
-    chan->channel.drone_jointime = 0;
-    chan->channel.drone_joins = 0;
-    chan->channel.last_eI = 0;
-    chan->channel.floodtime = NULL;
-    chan->channel.floodnum = NULL;
 
     /* We _only_ put the dname (display name) in here so as not to confuse
      * any code later on. chan->name gets updated with the channel name as

+ 0 - 2
src/mod/channels.mod/channels.cc

@@ -655,8 +655,6 @@ void remove_channel(struct chanset_t *chan)
    }
    delete chan->bot_roles;
    delete chan->role_bots;
-   delete chan->channel.floodtime;
-   delete chan->channel.floodnum;
    free(chan);
 }
 

+ 11 - 22
src/mod/irc.mod/chan.cc

@@ -1207,13 +1207,10 @@ void recheck_channel_modes(struct chanset_t *chan)
   }
 }
 
-static void check_this_member(struct chanset_t *chan, char *nick, struct flag_record *fr)
+static void check_this_member(struct chanset_t *chan, memberlist *m,
+    struct flag_record *fr)
 {
-  if (match_my_nick(nick) || !me_op(chan))
-    return;
-
-  memberlist *m = ismember(chan, nick);
-  if (!m)
+  if (!m || m->is_me || !me_op(chan))
     return;
 
   /* +d or bitch and not an op
@@ -1330,7 +1327,7 @@ void check_this_user(char *hand, int del, char *host)
       }
       if (check_member) {
         get_user_flagrec(u, &fr, chan->dname, chan);
-        check_this_member(chan, m->nick, &fr);
+        check_this_member(chan, m, &fr);
       }
     }
   }
@@ -1581,7 +1578,7 @@ void recheck_channel(struct chanset_t *chan, int dobans)
       //Already a bot opped, dont bother resetting masks
       if (glob_bot(fr) && chan_hasop(m) && !m->is_me)
         stop_reset = 1;
-      check_this_member(chan, m->nick, &fr);
+      check_this_member(chan, m, &fr);
     }
 
     //Only reset masks if the bot has already received the ban list before (meaning it has already been opped once)
@@ -2141,7 +2138,8 @@ static int got315(char *from, char *msg)
     force_join_chan(chan);
   } else {
     me->is_me = 1;
-    me->joined = now;				/* set this to keep the whining masses happy */
+    if (!me->joined)
+      me->joined = now;				/* set this to keep the whining masses happy */
     rebalance_roles_chan(chan);
     if (me_op(chan))
       recheck_channel(chan, 2);
@@ -3108,22 +3106,13 @@ static int gotnick(char *from, char *msg)
 
       detect_chan_flood(m, from, chan, FLOOD_NICK);
 
-      /* don't fill the serverqueue with modes or kicks in a nickflood */
-      if (chan_sentkick(m) || chan_sentdeop(m) || chan_sentop(m) ||
-	  chan_sentdevoice(m) || chan_sentvoice(m))
-	m->flags |= STOPCHECK;
       /* Any pending kick or mode to the old nick is lost. */
-	m->flags &= ~(SENTKICK | SENTDEOP | SENTOP |
-		      SENTVOICE | SENTDEVOICE);
-
-
-      /* make sure they stay devoiced if EVOICE! */
+      m->flags &= ~(SENTKICK | SENTDEOP | SENTOP |
+          SENTVOICE | SENTDEVOICE);
 
       /* nick-ban or nick is +k or something? */
-      if (!chan_stopcheck(m)) {
-	get_user_flagrec(m->user, &fr, chan->dname, chan);
-	check_this_member(chan, m->nick, &fr);
-      }
+      get_user_flagrec(m->user, &fr, chan->dname, chan);
+      check_this_member(chan, m, &fr);
     }
   }
   return 0;

+ 3 - 2
src/mod/server.mod/server.cc

@@ -117,7 +117,7 @@ bd::HashTable<bd::String, fish_data_t*> FishKeys;
 static bool double_warned = 0;
 
 static void empty_msgq(void);
-static void disconnect_server(int, int);
+static void disconnect_server(int);
 static void calc_penalty(char *, size_t);
 static bool fast_deq(int);
 static char *splitnicks(char **);
@@ -1090,7 +1090,8 @@ static void server_check_lag()
     waiting_for_awake = 1;
   } else if (servidx != -1 && waiting_for_awake && ((now - lastpingtime) >= stoned_timeout)) {
     // Not checking server_online as this will handle connect timeouts as well where the connect() works, but the server gets stoned afterwards
-    disconnect_server(servidx, DO_LOST);
+    disconnect_server(servidx);
+    lostdcc(servidx);
     putlog(LOG_SERV, "*", "Server got stoned; jumping...");
   }
 }

+ 0 - 2
src/mod/server.mod/server.h

@@ -12,8 +12,6 @@
 #include <bdlib/src/String.h>
 #include <bdlib/src/HashTable.h>
 
-#define DO_LOST 1
-#define NO_LOST 0
 #define DEQ_RATE 200
 
 #define fixcolon(x)             do {                                    \

+ 32 - 31
src/mod/server.mod/servmsg.cc

@@ -320,6 +320,7 @@ got004(char *from, char *msg)
   bool connect_burst = 0;
 
   /* cookies won't work on ircu or Unreal or snircd */
+  cookies_disabled = false;
   if (strstr(tmp, "u2.") || strstr(tmp, "Unreal") || strstr(tmp, "snircd")) {
     putlog(LOG_DEBUG, "*", "Disabling cookies as they are not supported on %s", cursrvname);
     cookies_disabled = true;
@@ -490,7 +491,8 @@ void nuke_server(const char *reason)
       dprintf(-serv, "QUIT :%s\n", reason);
 
     sleep(1);
-    disconnect_server(servidx, DO_LOST);
+    disconnect_server(servidx);
+    lostdcc(servidx);
   }
 }
 
@@ -1414,22 +1416,20 @@ static int gotmode(char *from, char *msg)
 static void end_burstmode();
 void irc_init();
 
-static void disconnect_server(int idx, int dolost)
+static void disconnect_server(int idx)
 {
+  server_online = 0;
   if ((serv != dcc[idx].sock) && serv >= 0)
     killsock(serv);
   if (dcc[idx].sock >= 0)
     killsock(dcc[idx].sock);
-
   dcc[idx].sock = -1;
   serv = -1;
-  servidx = -1;
-  server_online = 0;
-  use_monitor = 0;
-  cookies_disabled = false;
-  floodless = 0;
   botuserhost[0] = 0;
   botuserip[0] = 0; 
+  /* Features should have a struct that can be bzero'd */
+  use_monitor = 0;
+  floodless = 0;
   use_penalties = 0;
   use_354 = 0;
   deaf_char = 0;
@@ -1442,34 +1442,16 @@ static void disconnect_server(int idx, int dolost)
   have_cnotice = 0;
   use_flood_count = 0;
   modesperline = 0;
-  if (dolost) {
-    Auth::DeleteAll();
-    trying_server = 0;
-    lostdcc(idx);
-  }
+  trying_server = 0;
   end_burstmode();
-  if (reset_chans == 2)
-    irc_init();
-  reset_chans = 0;
   keepnick = 1;
-  /* Invalidate the cmd_swhois cache callback data */
-  for (int i = 0; i < dcc_total; i++) {
-    if (dcc[i].type && dcc[i].whois[0]) {
-      dcc[i].whois[0] = 0;
-      dcc[i].whowas = 0;
-    }
-  }
-
-  if (!segfaulted) //Avoid if crashed, too many free()/malloc() in here
-    for (struct chanset_t *chan = chanset; chan; chan = chan->next)
-      clear_channel(chan, 1);
-
 }
 
 static void eof_server(int idx)
 {
   putlog(LOG_SERV, "*", "Disconnected from %s (EOF)", dcc[idx].host);
-  disconnect_server(idx, DO_LOST);
+  disconnect_server(idx);
+  lostdcc(idx);
 }
 
 static void display_server(int idx, char *buf, size_t bufsiz)
@@ -1481,7 +1463,25 @@ static void connect_server(void);
 
 static void kill_server(int idx, void *x)
 {
-  disconnect_server(idx, NO_LOST);	/* eof_server will lostdcc() it. */
+  disconnect_server(idx);
+  Auth::DeleteAll();
+  if (reset_chans == 2) {
+    irc_init();
+  }
+  reset_chans = 0;
+  /* Invalidate the cmd_swhois cache callback data */
+  for (int i = 0; i < dcc_total; i++) {
+    if (dcc[i].type && dcc[i].whois[0]) {
+      dcc[i].whois[0] = 0;
+      dcc[i].whowas = 0;
+    }
+  }
+  if (!segfaulted) { //Avoid if crashed, too many free()/malloc() in here
+    for (struct chanset_t *chan = chanset; chan; chan = chan->next) {
+      clear_channel(chan, 1);
+    }
+  }
+  servidx = -1;
   /* A new server connection will be automatically initiated in
      about 2 seconds. */
 }
@@ -1489,7 +1489,8 @@ static void kill_server(int idx, void *x)
 static void timeout_server(int idx)
 {
   putlog(LOG_SERV, "*", "Timeout: connect to %s", dcc[idx].host);
-  disconnect_server(idx, DO_LOST);
+  disconnect_server(idx);
+  lostdcc(idx);
 }
 
 static void server_activity(int, char *, int);