aboutsummaryrefslogtreecommitdiff
path: root/src/mode.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2022-04-16 20:09:53 +0100
committerGravatar Sadie Powell2022-04-16 20:09:53 +0100
commit3b71730688285e03ae86af6a7a79d713de18ee97 (patch)
treebc1cebe4d6f6d0abdf3be0b8ca211f0683501a95 /src/mode.cpp
parentMerge branch 'insp3' into master. (diff)
Refactor CleanMask to cover more edge cases.
Test results from during refactoring: PASS: => *!*@* PASS: ! => *!*@* PASS: @ => *!*@* PASS: !foo@bar => *!foo@bar PASS: fo:ob:ar => *!*@fo:ob:ar PASS: foo!@bar => foo!*@bar PASS: foo!bar => foo!bar@* PASS: foo!bar@ => foo!bar@* PASS: foo.bar => *!*@foo.bar PASS: foo@bar => *!foo@bar PASS: !foo@ => *!foo@* PASS: foo => foo!*@* PASS: foo! => foo!*@*
Diffstat (limited to 'src/mode.cpp')
-rw-r--r--src/mode.cpp50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/mode.cpp b/src/mode.cpp
index 3291bb55e..dd7f6d4da 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -507,35 +507,45 @@ void ModeParser::ShowListModeList(User* user, Channel* chan, ModeHandler* mh)
void ModeParser::CleanMask(std::string &mask)
{
- std::string::size_type pos_of_pling = mask.find_first_of('!');
- std::string::size_type pos_of_at = mask.find_first_of('@');
- std::string::size_type pos_of_dot = mask.find_first_of('.');
- std::string::size_type pos_of_colons = mask.find("::"); /* Because ipv6 addresses are colon delimited -- double so it treats extban as nick */
+ auto pos_of_pling = mask.find_first_of('!');
+ auto pos_of_at = mask.find_first_of('@', pos_of_pling == std::string::npos ? 0 : pos_of_pling);
+ auto pos_of_hostchar = mask.find_first_of(":.", pos_of_at == std::string::npos ? 0 : pos_of_at);
- if ((pos_of_pling == std::string::npos) && (pos_of_at == std::string::npos))
+ if (pos_of_pling == mask.length()-1 || pos_of_at == mask.length()-1)
{
- /* Just a nick, or just a host - or clearly ipv6 (starting with :) */
- if ((pos_of_dot == std::string::npos) && (pos_of_colons == std::string::npos) && mask[0] != ':')
- {
- /* It has no '.' in it, it must be a nick. */
- mask.append("!*@*");
- }
+ // Malformed mask; needs * after the ! or @.
+ mask.append("*");
+ }
+
+ if (pos_of_pling == 0 || pos_of_at == 0)
+ {
+ // Malformed mask; needs * before the ! or @.
+ mask.insert(0, "*");
+ }
+
+ if (pos_of_pling == std::string::npos && pos_of_at == std::string::npos)
+ {
+ if (pos_of_hostchar == std::string::npos)
+ mask.append("!*@*"); // The mask looks like "nick".
else
- {
- /* Got a dot in it? Has to be a host */
- mask = "*!*@" + mask;
- }
+ mask.insert(0, "*!*@"); // The mask looks like "host".
}
- else if ((pos_of_pling == std::string::npos) && (pos_of_at != std::string::npos))
+ else if (pos_of_pling == std::string::npos && pos_of_at != std::string::npos)
{
- /* Has an @ but no !, its a user@host */
- mask = "*!" + mask;
+ // The mask looks like "user@host".
+ mask.insert(0, "*!");
+
}
- else if ((pos_of_pling != std::string::npos) && (pos_of_at == std::string::npos))
+ else if (pos_of_pling != std::string::npos && pos_of_at == std::string::npos)
{
- /* Has a ! but no @, it must be a nick!ident */
+ // The mask looks like "nick!user".
mask.append("@*");
}
+ else if (pos_of_at-pos_of_pling == 1)
+ {
+ // The mask looks like "nick!@host".
+ mask.insert(pos_of_at, "*");
+ }
}
ModeHandler::Id ModeParser::AllocateModeId(ModeHandler* mh)