summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2018-04-27 14:30:06 +0100
committerPeter Powell <petpow@saberuk.com>2018-08-26 11:33:19 +0100
commit4567a325b8cfc87ddf1aea1c0db7623d3b068931 (patch)
tree6f822c442abff8174c0e375b0d088a5dbfb08fa4 /src/modules
parent9d1b92d927028dfd89acb5c71f671c9d7f203494 (diff)
Implement proper CTCP parsing in MessageDetails.
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_anticaps.cpp21
-rw-r--r--src/modules/m_blockcaps.cpp19
-rw-r--r--src/modules/m_delayjoin.cpp12
-rw-r--r--src/modules/m_noctcp.cpp5
4 files changed, 29 insertions, 28 deletions
diff --git a/src/modules/m_anticaps.cpp b/src/modules/m_anticaps.cpp
index 755ab8bfa..6cb9b940b 100644
--- a/src/modules/m_anticaps.cpp
+++ b/src/modules/m_anticaps.cpp
@@ -216,23 +216,18 @@ class ModuleAntiCaps : public Module
// If the user is exempt from anticaps then we don't need
// to do anything else.
ModResult result = CheckExemption::Call(exemptionprov, user, channel, "anticaps");
- if (result == MOD_RES_ALLOW)
+ if (result == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
// If the message is a CTCP then we skip it unless it is
- // an ACTION in which case we skip the prefix and suffix.
- std::string::const_iterator text_begin = details.text.begin();
- std::string::const_iterator text_end = details.text.end();
- if (details.text[0] == '\1')
+ // an ACTION in which case we just check against the body.
+ std::string ctcpname;
+ std::string msgbody(details.text);
+ if (details.IsCTCP(ctcpname, msgbody))
{
// If the CTCP is not an action then skip it.
- if (details.text.compare(0, 8, "\1ACTION ", 8))
+ if (!irc::equals(ctcpname, "ACTION"))
return MOD_RES_PASSTHRU;
-
- // Skip the CTCP message characters.
- text_begin += 8;
- if (*details.text.rbegin() == '\1')
- text_end -= 1;
}
// Retrieve the anticaps config. This should never be
@@ -243,14 +238,14 @@ class ModuleAntiCaps : public Module
// If the message is shorter than the minimum length then
// we don't need to do anything else.
- size_t length = std::distance(text_begin, text_end);
+ size_t length = msgbody.length();
if (length < config->minlen)
return MOD_RES_PASSTHRU;
// Count the characters to see how many upper case and
// ignored (non upper or lower) characters there are.
size_t upper = 0;
- for (std::string::const_iterator iter = text_begin; iter != text_end; ++iter)
+ for (std::string::const_iterator iter = msgbody.begin(); iter != msgbody.end(); ++iter)
{
unsigned char chr = static_cast<unsigned char>(*iter);
if (uppercase.test(chr))
diff --git a/src/modules/m_blockcaps.cpp b/src/modules/m_blockcaps.cpp
index b79e126a3..fa780427c 100644
--- a/src/modules/m_blockcaps.cpp
+++ b/src/modules/m_blockcaps.cpp
@@ -60,31 +60,26 @@ public:
if (!c->GetExtBanStatus(user, 'B').check(!c->IsModeSet(bc)))
{
// If the message is a CTCP then we skip it unless it is
- // an ACTION in which case we strip the prefix and suffix.
- std::string::const_iterator text_begin = details.text.begin();
- std::string::const_iterator text_end = details.text.end();
- if (details.text[0] == '\1')
+ // an ACTION in which case we just check against the body.
+ std::string ctcpname;
+ std::string message(details.text);
+ if (details.IsCTCP(ctcpname, message))
{
// If the CTCP is not an action then skip it.
- if (details.text.compare(0, 8, "\1ACTION ", 8))
+ if (!irc::equals(ctcpname, "ACTION"))
return MOD_RES_PASSTHRU;
-
- // Skip the CTCP message characters.
- text_begin += 8;
- if (*details.text.rbegin() == '\1')
- text_end -= 1;
}
// If the message is shorter than the minimum length
// then we don't need to do anything else.
- size_t length = std::distance(text_begin, text_end);
+ size_t length = message.length();
if (length < minlen)
return MOD_RES_PASSTHRU;
// Count the characters to see how many upper case and
// ignored (non upper or lower) characters there are.
size_t upper = 0;
- for (std::string::const_iterator iter = text_begin; iter != text_end; ++iter)
+ for (std::string::const_iterator iter = message.begin(); iter != message.end(); ++iter)
{
unsigned char chr = static_cast<unsigned char>(*iter);
if (uppercase.test(chr))
diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp
index 7c557eb35..d157b97bc 100644
--- a/src/modules/m_delayjoin.cpp
+++ b/src/modules/m_delayjoin.cpp
@@ -91,6 +91,16 @@ class ModuleDelayJoin : public Module
ModResult OnRawMode(User* user, Channel* channel, ModeHandler* mh, const std::string& param, bool adding) CXX11_OVERRIDE;
};
+// TODO: make RevealUser accessible from DelayJoinMode and get rid of this.
+class DummyMessageDetails : public MessageDetails
+{
+public:
+ DummyMessageDetails() : MessageDetails(MSG_PRIVMSG, "", ClientProtocol::TagMap()) { }
+ bool IsCTCP(std::string& name, std::string& body) const CXX11_OVERRIDE { return false; }
+ bool IsCTCP(std::string&) const CXX11_OVERRIDE { return false; }
+ bool IsCTCP() const CXX11_OVERRIDE { return false; }
+};
+
ModeAction DelayJoinMode::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
{
/* no change */
@@ -104,7 +114,7 @@ ModeAction DelayJoinMode::OnModeChange(User* source, User* dest, Channel* channe
* they remain permanently invisible on this channel!
*/
MessageTarget msgtarget(channel, 0);
- MessageDetails msgdetails(MSG_PRIVMSG, "", ClientProtocol::TagMap());
+ DummyMessageDetails msgdetails;
const Channel::MemberMap& users = channel->GetUsers();
for (Channel::MemberMap::const_iterator n = users.begin(); n != users.end(); ++n)
{
diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp
index dbfe55eac..54960a88e 100644
--- a/src/modules/m_noctcp.cpp
+++ b/src/modules/m_noctcp.cpp
@@ -43,10 +43,11 @@ class ModuleNoCTCP : public Module
{
if ((target.type == MessageTarget::TYPE_CHANNEL) && (IS_LOCAL(user)))
{
- Channel* c = target.Get<Channel>();
- if ((details.text.empty()) || (details.text[0] != '\001') || (!strncmp(details.text.c_str(),"\1ACTION ", 8)) || (details.text == "\1ACTION\1") || (details.text == "\1ACTION"))
+ std::string ctcpname;
+ if (!details.IsCTCP(ctcpname) || irc::equals(ctcpname, "ACTION"))
return MOD_RES_PASSTHRU;
+ Channel* c = target.Get<Channel>();
ModResult res = CheckExemption::Call(exemptionprov, user, c, "noctcp");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;