From 7866c42d8f80723d07cf38ed9413857164b55e00 Mon Sep 17 00:00:00 2001 From: danieldg Date: Thu, 14 Jan 2010 15:23:24 +0000 Subject: [PATCH] Allow maxtargets to be bypassed in LoopCall for JOIN git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12255 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/command_parse.h | 26 ++-------------- src/command_parse.cpp | 65 ++++++--------------------------------- src/commands/cmd_join.cpp | 4 +-- 3 files changed, 14 insertions(+), 81 deletions(-) diff --git a/include/command_parse.h b/include/command_parse.h index f374673f2..ac401ff67 100644 --- a/include/command_parse.h +++ b/include/command_parse.h @@ -101,33 +101,11 @@ class CoreExport CommandParser * @param The number of items in the parameters list * @param splithere The first parameter index to split as a comma seperated list * @param extra The second parameter index to split as a comma seperated list + * @param usemax Limit the command to MaxTargets targets * @return This function will return 1 when there are no more parameters to process. When this occurs, its * caller should return without doing anything, otherwise it should continue into its main section of code. */ - int LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere, unsigned int extra); - - /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list. - * There are two overriden versions of this method, one of which takes two potential lists and the other takes one. - * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once, - * the channel names and their keys as follows: - * - * JOIN #chan1,#chan2,#chan3 key1,,key3 - * - * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating - * two instances of irc::commasepstream and reading them both together until the first runs out of tokens. - * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc. - * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam. - * - * @param user The user who sent the command - * @param CommandObj the command object to call for each parameter in the list - * @param parameters Parameter list as an array of array of char (that's not a typo). - * @param The number of items in the parameters list - * @param splithere The first parameter index to split as a comma seperated list - * @param extra The second parameter index to split as a comma seperated list - * @return This function will return 1 when there are no more parameters to process. When this occurs, its - * caller should return without doing anything, otherwise it should continue into its main section of code. - */ - int LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere); + int LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere, unsigned int extra = -1, bool usemax = true); /** Take a raw input buffer from a recvq, and process it on behalf of a user. * @param buffer The buffer line to process diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 679f4e9ae..216981773 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -55,11 +55,14 @@ int InspIRCd::PassCompare(Extensible* ex, const std::string &data, const std::st * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc. * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam. */ -int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere, unsigned int extra) +int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere, unsigned int extra, bool usemax) { if (splithere >= parameters.size()) return 0; + if (extra >= parameters.size()) + extra = -1; + /* First check if we have more than one item in the list, if we don't we return zero here and the handler * which called us just carries on as it was. */ @@ -75,7 +78,7 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector= 0 ? parameters[extra] : ""); std::string extrastuff; std::string item; unsigned int max = 0; @@ -84,72 +87,24 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vectorConfig->MaxTargets)) + while (items1.GetToken(item) && (!usemax || max++ < ServerInstance->Config->MaxTargets)) { if (dupes.find(item.c_str()) == dupes.end()) { - std::vector new_parameters; - - for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++) - new_parameters.push_back(parameters[t]); + std::vector new_parameters(parameters); if (!items2.GetToken(extrastuff)) extrastuff = ""; - new_parameters[splithere] = item.c_str(); - new_parameters[extra] = extrastuff.c_str(); - - CommandObj->Handle(new_parameters, user); - - dupes.insert(item.c_str()); - } - } - return 1; -} - -int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector& parameters, unsigned int splithere) -{ - if (splithere >= parameters.size()) - return 0; - - /* First check if we have more than one item in the list, if we don't we return zero here and the handler - * which called us just carries on as it was. - */ - if (parameters[splithere].find(',') == std::string::npos) - return 0; - - std::set dupes; - - /* Only one commasepstream here */ - irc::commasepstream items1(parameters[splithere]); - std::string item; - unsigned int max = 0; + new_parameters[splithere] = item; + if (extra >= 0) + new_parameters[extra] = extrastuff; - /* Parse the commasepstream until there are no tokens remaining. - * Each token we parse out, call the command handler that called us - * with it - */ - while (items1.GetToken(item) && (max++ < ServerInstance->Config->MaxTargets)) - { - if (dupes.find(item.c_str()) == dupes.end()) - { - std::vector new_parameters; - - for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++) - new_parameters.push_back(parameters[t]); - - new_parameters[splithere] = item.c_str(); - - /* Execute the command handler. */ CommandObj->Handle(new_parameters, user); dupes.insert(item.c_str()); } } - /* By returning 1 we tell our caller that nothing is to be done, - * as all the previous calls handled the data. This makes the parent - * return without doing any processing. - */ return 1; } diff --git a/src/commands/cmd_join.cpp b/src/commands/cmd_join.cpp index f3a97d31a..17a71688a 100644 --- a/src/commands/cmd_join.cpp +++ b/src/commands/cmd_join.cpp @@ -50,7 +50,7 @@ CmdResult CommandJoin::Handle (const std::vector& parameters, User { if (parameters.size() > 1) { - if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1)) + if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1, false)) return CMD_SUCCESS; if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax)) @@ -61,7 +61,7 @@ CmdResult CommandJoin::Handle (const std::vector& parameters, User } else { - if (ServerInstance->Parser->LoopCall(user, this, parameters, 0)) + if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, -1, false)) return CMD_SUCCESS; if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax)) -- 2.39.5