From aa456d152d681da1f268a61615964655844f4beb Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Thu, 14 Jun 2012 10:05:40 +0200 Subject: [PATCH] implement vote command restrictions --- commands.cfg | 6 +-- qcsrc/server/command/vote.qc | 78 +++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/commands.cfg b/commands.cfg index 9386b3c09..6b82c32ea 100644 --- a/commands.cfg +++ b/commands.cfg @@ -239,7 +239,9 @@ alias unban "qc_cmd_sv unban ${* ?}" // Remove // other aliases for ban commands alias bans "banlist" -// character classes (intersected with 32..126 minus ", $, ;, ^, \ - if you want these, include them explicitly) +// character classes (intersected with 32..126 minus ", $, ;, ^, \ - if you +// want these, include them explicitly) +// note that QC code always forbids $ and ; in VoteCommand_checknasty set _iscntrl "" set _isblank " " set _ispunct "!#%&'()*+,-./:<=>?@[]_`{|}~" @@ -259,8 +261,6 @@ set _isspace "$_isblank" // restriction is specified as followed by instances of ';' // and the optional character class to verify the argument by (no checking if // empty) -// as we use the semicolon as separator, we cannot include it directly -// so ; is written as ^^ and ;^ is written as ^^^ set sv_vote_command_restriction_restart "0" set sv_vote_command_restriction_fraglimit "1;$_isdigit" set sv_vote_command_restriction_chmap "1;$_isgraph" diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index aea89933a..3604f6fb1 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -507,30 +507,78 @@ string ValidateMap(string validated_map, entity caller) return validated_map; } -float VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, float argc) +float VoteCommand_checkargs(float startpos, float argc) { - string first_command; - - first_command = argv(startpos); + float p, q, check; + string cvarname = strcat("sv_vote_command_cmdrestriction_", argv(startpos)); + string cmdrestriction = cvar_string(cvarname); // note: this warns on undefined cvar. We want that. + string charlist, arg; + float checkmate; - if not(VoteCommand_checkinlist(first_command, vote_list)) + if(cmdrestriction == "") + return TRUE; + + ++startpos; // skip command name + + // check minimum arg count + + // 0 args: argc == startpos + // 1 args: argc == startpos + 1 + // ... + + if((argc - startpos) < stof(cmdrestriction)) return FALSE; - if(argc < startpos) // These commands won't work without arguments + p = strstrofs(cmdrestriction, ";", 0); // find first semicolon + + for(;;) { - switch(first_command) + if(startpos >= argc) // all args checked? GOOD + return TRUE; + + if(p < 0) // no more args? FAIL + return FALSE; + + // cut to next semicolon + q = strstrofs(cmdrestriction, ";", p+1); // find next semicolon + if(q < 0) + charlist = substring(cmdrestriction, p+1, -1); + else + charlist = substring(cmdrestriction, p+1, q - (p+1)); + + // in case we ever want to allow semicolons in VoteCommand_checknasty + // charlist = strreplace("^^", ";", charlist); + + if(charlist != "") { - case "map": - case "chmap": - case "gotomap": - case "kick": - case "kickban": - return FALSE; - - default: { break; } + // verify the arg only contains allowed chars + arg = argv(startpos); + checkmate = strlen(arg); + for(check = 0; check < checkmate; ++check) + if(strstrofs(charlist, substring(arg, check, 1), 0) < 0) + return FALSE; // not allowed character + // all characters are allowed. FINE. } + + ++startpos; + p = q; } + + return TRUE; +} + +float VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, float argc) +{ + string first_command; + first_command = argv(startpos); + + if not(VoteCommand_checkinlist(first_command, vote_list)) + return FALSE; + + if not(VoteCommand_checkargs(startpos, argc)) + return FALSE; + switch(first_command) // now go through and parse the proper commands to adjust as needed. { case "kick": -- 2.39.2