diff options
author | Sadie Powell <sadie@witchery.services> | 2024-06-24 14:29:55 +0100 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2024-06-24 14:29:55 +0100 |
commit | 693eeed762eac490b1289f8f4428ff0b5bbf1672 (patch) | |
tree | 974cbad287da04fc9e137d7f51092efd2e474acd /src/misc.cpp | |
parent | 6e5713d64a379fc64c7ff6658362d02b3618c3ca (diff) |
Rework how CTCP messages are sent and received.
Diffstat (limited to 'src/misc.cpp')
-rw-r--r-- | src/misc.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/misc.cpp b/src/misc.cpp index 8a0920fc1..0b760ea76 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -835,3 +835,50 @@ Anope::string Anope::Expand(const Anope::string &base, const Anope::string &frag return Anope::printf("%s%c%s", base.c_str(), separator, fragment.c_str()); } + +Anope::string Anope::FormatCTCP(const Anope::string &name, const Anope::string &value) +{ + if (value.empty()) + return Anope::printf("\1%s\1", name.c_str()); + + return Anope::printf("\1%s %s\1", name.c_str(), value.c_str()); +} + +bool Anope::ParseCTCP(const Anope::string &text, Anope::string &name, Anope::string &body) +{ + // According to draft-oakley-irc-ctcp-02 a valid CTCP must begin with SOH and + // contain at least one octet which is not NUL, SOH, CR, LF, or SPACE. As most + // of these are restricted at the protocol level we only need to check for SOH + // and SPACE. + if (text.length() < 2 || text[0] != '\x1' || text[1] == '\x1' || text[1] == ' ') + { + name.clear(); + body.clear(); + return false; + } + + auto end_of_name = text.find(' ', 2); + auto end_of_ctcp = *text.rbegin() == '\x1' ? 1 : 0; + if (end_of_name == std::string::npos) + { + // The CTCP only contains a name. + name = text.substr(1, text.length() - 1 - end_of_ctcp); + body.clear(); + return true; + } + + // The CTCP contains a name and a body. + name = text.substr(1, end_of_name - 1); + + auto start_of_body = text.find_first_not_of(' ', end_of_name + 1); + if (start_of_body == std::string::npos) + { + // The CTCP body is provided but empty. + body.clear(); + return true; + } + + // The CTCP body provided was non-empty. + body = text.substr(start_of_body, text.length() - start_of_body - end_of_ctcp); + return true; +} |