]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Validate mode parameters from ModeParser::ProcessSingle()
authorAttila Molnar <attilamolnar@hush.com>
Wed, 3 Sep 2014 12:52:00 +0000 (14:52 +0200)
committerAttila Molnar <attilamolnar@hush.com>
Wed, 3 Sep 2014 12:52:00 +0000 (14:52 +0200)
src/mode.cpp

index 3facc75222296b7770deb536b20172182b35eb9c..5f1f8225cf15d2e7766bb5b89550b658a8a348a8 100644 (file)
@@ -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;