filter out invisible message content on mode +M check
[ircu2.10.12-pk.git] / ircd / channel.c
index fd48bde4b2af4422ff81423b2e86d42f40879f11..a467750ea39496f483da2cad7b247b18a138e4ae 100644 (file)
@@ -2727,6 +2727,16 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
     noflood_value <<= 3;
     noflood_value |= flags;
     state->chptr->mode.noflood_value = noflood_value;
+  } else {
+    //removed the mode so free all flood objects
+    struct Membership *member;
+    for(member = state->chptr->members; member; member = member->next_member) {
+        struct MemberFlood *floodnode;
+        for(floodnode = member->flood; floodnode; floodnode = floodnode->next_memberflood) {} //simply walk to the end
+        floodnode->next_memberflood = free_MemberFlood;
+        free_MemberFlood  = floodnode;
+        member->flood = NULL;
+    }
   }
 }
 
@@ -4295,7 +4305,7 @@ void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr)
 int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
 {
   int amsg_time;
-
+  
   /* First on every message we check whether the mechanism is enabled.
    * If it is enabled, we check:
    *  - whether the channel has MODE_NOAMSGS
@@ -4309,6 +4319,59 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
    */
   amsg_time = feature_int(FEAT_NOAMSG_TIME);
   if(amsg_time > 0) {
+    /* first of all strip the message (filter out invisible content) */
+    char *stripped_message = MyMalloc(BUFSIZE + 1);
+    strcpy(stripped_message, msg);
+    char p = stripped_message[0];
+    int p_pos = 0;
+    int is_visible = 1, is_ccode = 0; j = 0;
+    char codes[5];
+    for(int i = 0; p != '\n'; p = stripped_message[++i]) {
+      if(c == 3) {
+        j = 0;
+        is_ccode = 1;
+      } else if(is_ccode) {
+        if((c >= 48 && c <= 57) || c == 44) {
+          if(ccode == 1) {
+            if(c == 44) {
+              ccode = 2;
+              codes[j++] = 0;
+              j = 0;
+            } else
+              codes[j++] = c;
+          } else {
+            //compare
+            if(c != codes[j++]) {
+             ccode = 3;
+            }
+          }
+        } else {
+          //END of color code...
+          is_ccode = 0;
+          if(ccode != 1 && codes[j] != 0) ccode = 3;
+          if(ccode == 1) {
+            codes[j] = 0;
+            for(int k = 0; k < j-1; k++) {
+              if(codes[k] != 48) {
+                is_visible = 1;
+                goto normalchar;
+              }
+            }
+            is_visible = 0;
+          } else if(ccode == 2) {
+            is_visible = 0;
+          } else if(ccode == 3) {
+            is_visible = 1;
+            goto normalchar;
+          }
+        }
+      } else {
+        :normalchar
+        if(is_visible)
+          stripped_message[p_pos++] = p;
+      }
+    }
+    stripped_message[p_pos++] = 0;
     /* Allocate a new buffer if there is none, yet. */
     if(!cli_user(cptr)->lastmsg) {
       cli_user(cptr)->lastmsg = MyMalloc(BUFSIZE + 1);
@@ -4316,16 +4379,18 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
     }
     if((chptr->mode.mode & MODE_NOAMSGS) &&
        ((cli_user(cptr)->lastmsg_time + amsg_time) >= CurrentTime) &&
-       (strcmp(cli_user(cptr)->lastmsg, msg) == 0)) {
+       (strcmp(cli_user(cptr)->lastmsg, stripped_message) == 0)) {
       cli_user(cptr)->lastmsg_time = CurrentTime;
       cli_user(cptr)->lastmsg_num++;
+      MyFree(stripped_message);
       if(cli_user(cptr)->lastmsg_num >= feature_int(FEAT_NOAMSG_NUM)) return 1;
       else return 0;
     }
     /* Message did not match so update the data. */
     cli_user(cptr)->lastmsg_time = CurrentTime;
     cli_user(cptr)->lastmsg_num = 0;
-    strcpy(cli_user(cptr)->lastmsg, msg);
+    strcpy(cli_user(cptr)->lastmsg, stripped_message);
+    MyFree(stripped_message);
   }
   return 0;
 }