chmode: end the grace period more intelligently (#84)

We were ending the flood grace period for any channel mode command other
than `MODE #foo [bq]` by means of a hardcoded check. I've moved that to
after we parse the mode string, so we can correctly identify all
requests to change modes and end the grace period on exactly those.

It would have been entirely possible to move the check even further down
and flood_endgrace on only mode commands that *actually* change modes,
but I don't like the idea of making it sensitive to external conditions.
This commit is contained in:
Ed Kellett 2020-11-30 09:24:32 +00:00 committed by GitHub
parent 6638c837cc
commit b860ad5ffa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 11 deletions

View file

@ -42,6 +42,7 @@
#include "s_assert.h" #include "s_assert.h"
#include "parse.h" #include "parse.h"
#include "msgbuf.h" #include "msgbuf.h"
#include "packet.h"
/* bitmasks for error returns, so we send once per call */ /* bitmasks for error returns, so we send once per call */
#define SM_ERR_NOTS 0x00000001 /* No TS on channel */ #define SM_ERR_NOTS 0x00000001 /* No TS on channel */
@ -1363,7 +1364,8 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
int cur_len, mlen, paralen, paracount, arglen, len; int cur_len, mlen, paralen, paracount, arglen, len;
int i, j, flags; int i, j, flags;
int dir = MODE_ADD; int dir = MODE_ADD;
int access_dir = MODE_QUERY; bool changes = false;
bool privileged_query = false;
int parn = 1; int parn = 1;
int errors = 0; int errors = 0;
int alevel; int alevel;
@ -1452,10 +1454,10 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
*mbuf++ = c; *mbuf++ = c;
if (effective_dir != MODE_QUERY && access_dir == MODE_QUERY) if (effective_dir != MODE_QUERY)
access_dir = effective_dir; changes = true;
if (effective_dir == MODE_QUERY && cm->flags & CHM_OPS_QUERY) if (effective_dir == MODE_QUERY && cm->flags & CHM_OPS_QUERY)
access_dir = MODE_OP_QUERY; privileged_query = true;
ms->cm = cm; ms->cm = cm;
ms->dir = effective_dir; ms->dir = effective_dir;
@ -1481,6 +1483,12 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
/* XXX we could reject excess params here */ /* XXX we could reject excess params here */
} }
/* Finish the flood grace period if we were asked to do anything */
if (changes && MyClient(source_p) && !IsFloodDone(source_p))
{
flood_endgrace(source_p);
}
mend = ms; mend = ms;
if (parn > 1) if (parn > 1)
@ -1492,6 +1500,9 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
{ {
*mbuf = '\0'; *mbuf = '\0';
} }
int access_dir = privileged_query ? MODE_OP_QUERY :
changes ? MODE_ADD :
MODE_QUERY;
alevel = get_channel_access(source_p, chptr, msptr, access_dir, modebuf); alevel = get_channel_access(source_p, chptr, msptr, access_dir, modebuf);
for (ms = modesets; ms < mend; ms++) for (ms = modesets; ms < mend; ms++)

View file

@ -138,13 +138,6 @@ m_mode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
{ {
msptr = find_channel_membership(chptr, source_p); msptr = find_channel_membership(chptr, source_p);
/* Finish the flood grace period... */
if(MyClient(source_p) && !IsFloodDone(source_p))
{
if(!((parc == 3) && (parv[2][0] == 'b' || parv[2][0] == 'q') && (parv[2][1] == '\0')))
flood_endgrace(source_p);
}
set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n); set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n);
} }
} }