diff options
author | Attila Molnar <attilamolnar@hush.com> | 2014-09-03 14:52:00 +0200 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-09-03 14:52:00 +0200 |
commit | 117f19aec0cdadf9a106c3e5db8f7c3d0d8bbbc9 (patch) | |
tree | 00e554d36ccc5fc19e2f0d01d5639e6c486aef40 /src | |
parent | 3d958279c6c4d352132ea50836a2b7b1d3be5434 (diff) |
Validate mode parameters from ModeParser::ProcessSingle()
Diffstat (limited to 'src')
-rw-r--r-- | src/mode.cpp | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/src/mode.cpp b/src/mode.cpp index 3facc7522..5f1f8225c 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -436,19 +436,9 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user, } std::string parameter; - int pcnt = mh->GetNumParams(adding); - if (pcnt && param_at == parameters.size()) - { - /* No parameter, continue to the next mode */ - mh->OnParameterMissing(user, targetuser, targetchannel); - continue; - } - else if (pcnt) + if (mh->GetNumParams(adding) && param_at < parameters.size()) { parameter = parameters[param_at++]; - /* Make sure the user isn't trying to slip in an invalid parameter */ - if ((parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos)) - continue; if ((flags & MODE_MERGE) && targetchannel && targetchannel->IsModeSet(mh) && !mh->IsListMode()) { std::string ours = targetchannel->GetModeParameter(mh); @@ -472,6 +462,22 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User* user, } } +static bool IsModeParamValid(User* user, Channel* targetchannel, User* targetuser, const Modes::Change& item) +{ + // An empty parameter is never acceptable + if (item.param.empty()) + { + item.mh->OnParameterMissing(user, targetuser, targetchannel); + return false; + } + + // The parameter cannot begin with a ':' character or contain a space + if ((item.param[0] == ':') || (item.param.find(' ') != std::string::npos)) + return false; + + return true; +} + void ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags) { LastParse.clear(); @@ -486,7 +492,16 @@ void ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetu { Modes::Change& item = *i; ModeHandler* mh = item.mh; - ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, (!(flags & MODE_CHECKACCESS))); + + // If the mode is supposed to have a parameter then we first take a look at item.param + if (mh->GetNumParams(item.adding)) + { + // Skip the mode if the parameter does not pass basic validation + if (!IsModeParamValid(user, targetchannel, targetuser, item)) + continue; + } + + ModeAction ma = TryMode(user, targetuser, targetchannel, item, (!(flags & MODE_CHECKACCESS))); if (ma != MODEACTION_ALLOW) continue; |