diff options
-rw-r--r-- | include/inspircd.h | 8 | ||||
-rw-r--r-- | src/configparser.cpp | 4 | ||||
-rw-r--r-- | src/coremods/core_channel/cmd_invite.cpp | 10 | ||||
-rw-r--r-- | src/coremods/core_xline/cmd_eline.cpp | 7 | ||||
-rw-r--r-- | src/coremods/core_xline/cmd_gline.cpp | 7 | ||||
-rw-r--r-- | src/coremods/core_xline/cmd_kline.cpp | 7 | ||||
-rw-r--r-- | src/coremods/core_xline/cmd_qline.cpp | 7 | ||||
-rw-r--r-- | src/coremods/core_xline/cmd_zline.cpp | 7 | ||||
-rw-r--r-- | src/helperfuncs.cpp | 77 | ||||
-rw-r--r-- | src/modules/m_cban.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_chanhistory.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_dccallow.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_filter.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_repeat.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_rline.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_setidle.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_shun.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_svshold.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_timedbans.cpp | 6 |
19 files changed, 132 insertions, 62 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index a563edc7f..8ca2314eb 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -502,6 +502,14 @@ class CoreExport InspIRCd */ static unsigned long Duration(const std::string& str); + /** Calculate a duration in seconds from a string in the form 1y2w3d4h6m5s + * @param str A string containing a time in the form 1y2w3d4h6m5s + * (one year, two weeks, three days, four hours, six minutes and five seconds) + * @param duration The location to place the parsed duration valur + * @return Whether the duration was a valid format or not + */ + static bool Duration(const std::string& str, unsigned long& duration); + /** Determines whether a string contains a valid duration. * @param str A string containing a time in the form 1y2w3d4h6m5s * @return True if the string is a valid duration; otherwise, false. diff --git a/src/configparser.cpp b/src/configparser.cpp index e4bf4bd71..abdf6f3de 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -609,14 +609,14 @@ unsigned long ConfigTag::getDuration(const std::string& key, unsigned long def, if (!readString(key, duration)) return def; - if (!InspIRCd::IsValidDuration(duration)) + unsigned long ret; + if (!InspIRCd::Duration(duration, ret)) { ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "Value of <" + tag + ":" + key + "> at " + getTagLocation() + " is not a duration; value set to " + ConvToStr(def) + "."); return def; } - unsigned long ret = InspIRCd::Duration(duration); CheckRange(tag, key, ret, def, min, max); return ret; } diff --git a/src/coremods/core_channel/cmd_invite.cpp b/src/coremods/core_channel/cmd_invite.cpp index ebb95f1b4..c26318337 100644 --- a/src/coremods/core_channel/cmd_invite.cpp +++ b/src/coremods/core_channel/cmd_invite.cpp @@ -51,7 +51,15 @@ CmdResult CommandInvite::Handle(User* user, const Params& parameters) if (parameters.size() >= 3) { if (IS_LOCAL(user)) - timeout = ServerInstance->Time() + InspIRCd::Duration(parameters[2]); + { + unsigned long duration; + if (!InspIRCd::Duration(parameters[2], duration)) + { + user->WriteNotice("*** Invalid duration for invite"); + return CMD_FAILURE; + } + timeout = ServerInstance->Time() + duration; + } else if (parameters.size() > 3) timeout = ConvToNum<time_t>(parameters[3]); } diff --git a/src/coremods/core_xline/cmd_eline.cpp b/src/coremods/core_xline/cmd_eline.cpp index 0cb52298c..a3a4d9466 100644 --- a/src/coremods/core_xline/cmd_eline.cpp +++ b/src/coremods/core_xline/cmd_eline.cpp @@ -58,7 +58,12 @@ CmdResult CommandEline::Handle(User* user, const Params& parameters) if (InsaneBan::MatchesEveryone(ih.first+"@"+ih.second, matcher, user, "E", "hostmasks")) return CMD_FAILURE; - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for E-line"); + return CMD_FAILURE; + } ELine* el = new ELine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); if (ServerInstance->XLines->AddLine(el, user)) { diff --git a/src/coremods/core_xline/cmd_gline.cpp b/src/coremods/core_xline/cmd_gline.cpp index 79b3ce21f..a9de707c4 100644 --- a/src/coremods/core_xline/cmd_gline.cpp +++ b/src/coremods/core_xline/cmd_gline.cpp @@ -64,7 +64,12 @@ CmdResult CommandGline::Handle(User* user, const Params& parameters) return CMD_FAILURE; } - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for G-line"); + return CMD_FAILURE; + } GLine* gl = new GLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); if (ServerInstance->XLines->AddLine(gl, user)) { diff --git a/src/coremods/core_xline/cmd_kline.cpp b/src/coremods/core_xline/cmd_kline.cpp index 0f04224d6..9b474d16c 100644 --- a/src/coremods/core_xline/cmd_kline.cpp +++ b/src/coremods/core_xline/cmd_kline.cpp @@ -64,7 +64,12 @@ CmdResult CommandKline::Handle(User* user, const Params& parameters) return CMD_FAILURE; } - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for K-line"); + return CMD_FAILURE; + } KLine* kl = new KLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); if (ServerInstance->XLines->AddLine(kl,user)) { diff --git a/src/coremods/core_xline/cmd_qline.cpp b/src/coremods/core_xline/cmd_qline.cpp index b75973861..893c8d213 100644 --- a/src/coremods/core_xline/cmd_qline.cpp +++ b/src/coremods/core_xline/cmd_qline.cpp @@ -44,7 +44,12 @@ CmdResult CommandQline::Handle(User* user, const Params& parameters) return CMD_FAILURE; } - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for Q-line"); + return CMD_FAILURE; + } QLine* ql = new QLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str()); if (ServerInstance->XLines->AddLine(ql,user)) { diff --git a/src/coremods/core_xline/cmd_zline.cpp b/src/coremods/core_xline/cmd_zline.cpp index 350f3270c..e81fc727f 100644 --- a/src/coremods/core_xline/cmd_zline.cpp +++ b/src/coremods/core_xline/cmd_zline.cpp @@ -62,7 +62,12 @@ CmdResult CommandZline::Handle(User* user, const Params& parameters) if (InsaneBan::MatchesEveryone(ipaddr, matcher, user, "Z", "ipmasks")) return CMD_FAILURE; - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for Z-line"); + return CMD_FAILURE; + } ZLine* zl = new ZLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ipaddr); if (ServerInstance->XLines->AddLine(zl,user)) { diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 6fb2a0ed0..94a5240c9 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -354,43 +354,38 @@ void InspIRCd::CheckRoot() * the ascii values 'm' and 'M' have the value '60', the indexes * for the ascii values 'D' and 'd' have a value of '86400', etc. */ -static const int duration_multi[] = +static const unsigned int duration_multi[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 86400, 1, 1, 1, 3600, - 1, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 604800, 1, 31557600, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 86400, 1, 1, 1, 3600, 1, 1, 1, 1, 60, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 604800, 1, 31557600, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86400, 0, 0, 0, 3600, 0, 0, 0, 0, 60, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 604800, 0, 31557600, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86400, 0, 0, 0, 3600, 0, 0, 0, 0, 60, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 604800, 0, 31557600, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -unsigned long InspIRCd::Duration(const std::string &str) +bool InspIRCd::Duration(const std::string& str, unsigned long& duration) { - unsigned char multiplier = 0; - long total = 0; - long times = 1; - long subtotal = 0; + unsigned long total = 0; + unsigned long subtotal = 0; /* Iterate each item in the string, looking for number or multiplier */ - for (std::string::const_reverse_iterator i = str.rbegin(); i != str.rend(); ++i) + for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) { /* Found a number, queue it onto the current number */ if ((*i >= '0') && (*i <= '9')) { - subtotal = subtotal + ((*i - '0') * times); - times = times * 10; + subtotal = (subtotal * 10) + (*i - '0'); } else { @@ -398,22 +393,26 @@ unsigned long InspIRCd::Duration(const std::string &str) * it multiplies the built up number by, multiply the total * and reset the built up number. */ - if (subtotal) - total += subtotal * duration_multi[multiplier]; + unsigned int multiplier = duration_multi[static_cast<unsigned char>(*i)]; + if (multiplier == 0) + return false; + + total += subtotal * multiplier; /* Next subtotal please */ subtotal = 0; - multiplier = *i; - times = 1; } } - if (multiplier) - { - total += subtotal * duration_multi[multiplier]; - subtotal = 0; - } /* Any trailing values built up are treated as raw seconds */ - return total + subtotal; + duration = total + subtotal; + return true; +} + +unsigned long InspIRCd::Duration(const std::string& str) +{ + unsigned long out = 0; + InspIRCd::Duration(str, out); + return out; } bool InspIRCd::IsValidDuration(const std::string& duration) @@ -421,10 +420,10 @@ bool InspIRCd::IsValidDuration(const std::string& duration) for (std::string::const_iterator i = duration.begin(); i != duration.end(); ++i) { unsigned char c = *i; - if (((c >= '0') && (c <= '9')) || (c == 's') || (c == 'S')) + if (((c >= '0') && (c <= '9'))) continue; - if (duration_multi[c] == 1) + if (!duration_multi[c]) return false; } return true; diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp index 250acd2b5..e0768aa88 100644 --- a/src/modules/m_cban.cpp +++ b/src/modules/m_cban.cpp @@ -111,7 +111,12 @@ class CommandCBan : public Command else { // Adding - XXX todo make this respect <insane> tag perhaps.. - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for CBan"); + return CMD_FAILURE; + } const char *reason = (parameters.size() > 2) ? parameters[2].c_str() : "No reason supplied"; CBan* r = new CBan(ServerInstance->Time(), duration, user->nick.c_str(), reason, parameters[0].c_str()); diff --git a/src/modules/m_chanhistory.cpp b/src/modules/m_chanhistory.cpp index 47e27172c..1057e63b6 100644 --- a/src/modules/m_chanhistory.cpp +++ b/src/modules/m_chanhistory.cpp @@ -72,8 +72,8 @@ class HistoryMode : public ParamMode<HistoryMode, SimpleExtItem<HistoryList> > } unsigned int len = ConvToNum<unsigned int>(parameter.substr(0, colon)); - unsigned int time = InspIRCd::Duration(duration); - if (len == 0 || (len > maxlines && IS_LOCAL(source))) + unsigned long time; + if (!InspIRCd::Duration(duration, time) || len == 0 || (len > maxlines && IS_LOCAL(source))) { source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter)); return MODEACTION_DENY; diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 85f9d20d0..d9e26d28f 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -219,7 +219,11 @@ class CommandDccallow : public Command } else { - length = InspIRCd::Duration(parameters[1]); + if (!InspIRCd::Duration(parameters[1], length)) + { + user->WriteNotice("*** Invalid duration for DCC allow"); + return CMD_FAILURE; + } } if (!InspIRCd::IsValidMask(mask)) diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index 357fbf738..0c8b81e4b 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -251,7 +251,11 @@ CmdResult CommandFilter::Handle(User* user, const Params& parameters) { if (parameters.size() >= 5) { - duration = InspIRCd::Duration(parameters[3]); + if (!InspIRCd::Duration(parameters[3], duration)) + { + user->WriteNotice("*** Invalid duration for filter"); + return CMD_FAILURE; + } reasonindex = 4; } else diff --git a/src/modules/m_repeat.cpp b/src/modules/m_repeat.cpp index bd4206166..a8dd49e2d 100644 --- a/src/modules/m_repeat.cpp +++ b/src/modules/m_repeat.cpp @@ -34,7 +34,7 @@ class ChannelSettings unsigned int Backlog; unsigned int Lines; unsigned int Diff; - unsigned int Seconds; + unsigned long Seconds; void serialize(std::string& out) const { @@ -277,7 +277,10 @@ class RepeatMode : public ParamMode<RepeatMode, SimpleExtItem<ChannelSettings> > if ((settings.Lines = ConvToNum<unsigned int>(item)) == 0) return false; - if ((!stream.GetToken(item)) || ((settings.Seconds = InspIRCd::Duration(item)) == 0)) + if (!InspIRCd::Duration(item, settings.Seconds)) + return false; + + if ((!stream.GetToken(item)) || (settings.Seconds == 0)) // Required parameter missing return false; diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index c1eeb7b9a..77b3bc3aa 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -147,7 +147,12 @@ class CommandRLine : public Command { // Adding - XXX todo make this respect <insane> tag perhaps.. - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for R-line"); + return CMD_FAILURE; + } XLine *r = NULL; try diff --git a/src/modules/m_setidle.cpp b/src/modules/m_setidle.cpp index 37984030b..8bca7000b 100644 --- a/src/modules/m_setidle.cpp +++ b/src/modules/m_setidle.cpp @@ -40,8 +40,8 @@ class CommandSetidle : public SplitCommand CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE { - int idle = InspIRCd::Duration(parameters[0]); - if (idle < 1) + unsigned long idle; + if (!InspIRCd::Duration(parameters[0], idle)) { user->WriteNumeric(ERR_INVALIDIDLETIME, "Invalid idle time."); return CMD_FAILURE; diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index 91933e7c4..e4fb2c11d 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -90,7 +90,11 @@ class CommandShun : public Command std::string expr; if (parameters.size() > 2) { - duration = InspIRCd::Duration(parameters[1]); + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for SHUN"); + return CMD_FAILURE; + } expr = parameters[2]; } else diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index 8eecd377d..52c250fef 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -127,7 +127,12 @@ class CommandSvshold : public Command if (parameters.size() < 3) return CMD_FAILURE; - unsigned long duration = InspIRCd::Duration(parameters[1]); + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) + { + user->WriteNotice("*** Invalid duration for SVSHOLD"); + return CMD_FAILURE; + } SVSHold* r = new SVSHold(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str()); if (ServerInstance->XLines->AddLine(r, user)) diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 058028f61..32b376c79 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -84,13 +84,13 @@ class CommandTban : public Command } TimedBan T; - unsigned long duration = InspIRCd::Duration(parameters[1]); - unsigned long expire = duration + ServerInstance->Time(); - if (duration < 1) + unsigned long duration; + if (!InspIRCd::Duration(parameters[1], duration)) { user->WriteNotice("Invalid ban time"); return CMD_FAILURE; } + unsigned long expire = duration + ServerInstance->Time(); std::string mask = parameters[2]; bool isextban = ((mask.size() > 2) && (mask[1] == ':')); if (!isextban && !InspIRCd::IsValidMask(mask)) |