summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h8
-rw-r--r--src/configparser.cpp4
-rw-r--r--src/coremods/core_channel/cmd_invite.cpp10
-rw-r--r--src/coremods/core_xline/cmd_eline.cpp7
-rw-r--r--src/coremods/core_xline/cmd_gline.cpp7
-rw-r--r--src/coremods/core_xline/cmd_kline.cpp7
-rw-r--r--src/coremods/core_xline/cmd_qline.cpp7
-rw-r--r--src/coremods/core_xline/cmd_zline.cpp7
-rw-r--r--src/helperfuncs.cpp77
-rw-r--r--src/modules/m_cban.cpp7
-rw-r--r--src/modules/m_chanhistory.cpp4
-rw-r--r--src/modules/m_dccallow.cpp6
-rw-r--r--src/modules/m_filter.cpp6
-rw-r--r--src/modules/m_repeat.cpp7
-rw-r--r--src/modules/m_rline.cpp7
-rw-r--r--src/modules/m_setidle.cpp4
-rw-r--r--src/modules/m_shun.cpp6
-rw-r--r--src/modules/m_svshold.cpp7
-rw-r--r--src/modules/m_timedbans.cpp6
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))