aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Sadie Powell2021-06-18 13:16:11 +0100
committerGravatar Sadie Powell2021-06-18 13:16:11 +0100
commit613348298d35963d276cff7f70ddd3f8abb3272f (patch)
treedb8cd675bb297c630594a35cd0cc8b99316c354c /src
parentAdd the bootwait and splitwait options to connectban. (diff)
Fix some weirdness with sign conversion and channel limits.
Reported by jessicara.
Diffstat (limited to 'src')
-rw-r--r--src/coremods/core_channel/cmode_l.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/coremods/core_channel/cmode_l.cpp b/src/coremods/core_channel/cmode_l.cpp
index 5b5b28554..8708f4722 100644
--- a/src/coremods/core_channel/cmode_l.cpp
+++ b/src/coremods/core_channel/cmode_l.cpp
@@ -41,8 +41,21 @@ bool ModeChannelLimit::ResolveModeConflict(std::string &their_param, const std::
ModeAction ModeChannelLimit::OnSet(User* user, Channel* chan, std::string& parameter)
{
size_t limit = ConvToNum<size_t>(parameter);
- if (limit < minlimit)
- return MODEACTION_DENY;
+ if (limit < minlimit || limit > INTPTR_MAX)
+ {
+ if (IS_LOCAL(user))
+ {
+ // If the setter is local then we can safely just reject this here.
+ user->WriteNumeric(Numerics::InvalidModeParameter(chan, this, parameter));
+ return MODEACTION_DENY;
+ }
+ else
+ {
+ // If the setter is remote we *must* set the mode to avoid a desync
+ // so instead clamp it to the allowed range instead.
+ limit = std::min<size_t>(std::max(limit, minlimit), INTPTR_MAX);
+ }
+ }
ext.set(chan, limit);
return MODEACTION_ALLOW;
@@ -50,5 +63,5 @@ ModeAction ModeChannelLimit::OnSet(User* user, Channel* chan, std::string& param
void ModeChannelLimit::SerializeParam(Channel* chan, intptr_t n, std::string& out)
{
- out += ConvToStr(n);
+ out += ConvToStr(static_cast<size_t>(n));
}