From 153587f0cb27956a8966fc4f71cb80de987b07cb Mon Sep 17 00:00:00 2001 From: BjossiAlfreds Date: Sat, 24 Sep 2022 01:07:08 +0000 Subject: [PATCH] Prevent crash or memory corruption when flood_msgs is too low or too high --- src/game/g_cmds.c | 106 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 0b645ec0..74ef8815 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1061,14 +1061,81 @@ Cmd_Wave_f(edict_t *ent) } } +static qboolean +flooded(edict_t *ent) +{ + gclient_t *cl; + int i; + int num_msgs; + int mx; + + if (!ent) + { + return false; + } + + if (!deathmatch->value && !coop->value) + { + return false; + } + + num_msgs = flood_msgs->value; + if (num_msgs <= 0) + { + return false; + } + + cl = ent->client; + mx = sizeof(cl->flood_when) / sizeof(cl->flood_when[0]); + + if (num_msgs > mx) + { + gi.dprintf("flood_msgs lowered to max: 10\n"); + + num_msgs = mx; + gi.cvar_forceset("flood_msgs", "10"); + } + + if (level.time < cl->flood_locktill) + { + gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n", + (int)(cl->flood_locktill - level.time)); + + return true; + } + + i = (cl->flood_whenhead - num_msgs) + 1; + + if (i < 0) + { + i += mx; + } + + if (cl->flood_when[i] && + (level.time - cl->flood_when[i]) < flood_persecond->value) + { + cl->flood_locktill = level.time + flood_waitdelay->value; + + gi.cprintf(ent, PRINT_CHAT, + "Flood protection: You can't talk for %d seconds.\n", + (int)flood_waitdelay->value); + + return true; + } + + cl->flood_whenhead = (cl->flood_whenhead + 1) % mx; + cl->flood_when[cl->flood_whenhead] = level.time; + + return false; +} + void Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0) { - int i, j; + int j; edict_t *other; char *p; char text[2048]; - gclient_t *cl; if (!ent) { @@ -1080,6 +1147,11 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0) return; } + if (flooded(ent)) + { + return; + } + if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) { team = false; @@ -1121,36 +1193,6 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0) strcat(text, "\n"); - if (flood_msgs->value) - { - cl = ent->client; - - if (level.time < cl->flood_locktill) - { - gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n", - (int)(cl->flood_locktill - level.time)); - return; - } - - i = cl->flood_whenhead - flood_msgs->value + 1; - - if (i < 0) - { - i = (sizeof(cl->flood_when) / sizeof(cl->flood_when[0])) + i; - } - - if (cl->flood_when[i] && (level.time - cl->flood_when[i] < flood_persecond->value)) - { - cl->flood_locktill = level.time + flood_waitdelay->value; - gi.cprintf(ent, PRINT_CHAT, "Flood protection: You can't talk for %d seconds.\n", - (int)flood_waitdelay->value); - return; - } - - cl->flood_whenhead = (cl->flood_whenhead + 1) % (sizeof(cl->flood_when) / sizeof(cl->flood_when[0])); - cl->flood_when[cl->flood_whenhead] = level.time; - } - if (dedicated->value) { gi.cprintf(NULL, PRINT_CHAT, "%s", text);