diff options
author | Peter Powell <petpow@saberuk.com> | 2017-11-09 10:04:58 +0000 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2017-11-09 10:30:59 +0000 |
commit | 7f7ffef3b4d5dc6242918a48713d6fab96928a80 (patch) | |
tree | ab4b7a62f4d9daee8058297a1e69c17b9a1425f4 | |
parent | b76ff64daeeb1e1081cff93c611f730e5b1b051e (diff) |
Implement support for draft-brocklesby-irc-isupport-03 escapes.
-rw-r--r-- | include/isupportmanager.h | 6 | ||||
-rw-r--r-- | src/server.cpp | 26 |
2 files changed, 28 insertions, 4 deletions
diff --git a/include/isupportmanager.h b/include/isupportmanager.h index 3a0df78f9..e5eeb599e 100644 --- a/include/isupportmanager.h +++ b/include/isupportmanager.h @@ -26,6 +26,12 @@ class CoreExport ISupportManager /** The generated lines which are sent to clients. */ std::vector<Numeric::Numeric> cachedlines; + /** Escapes an ISUPPORT token value and appends it to the buffer. + * @param buffer The buffer to append to. + * @param value An ISUPPORT token value. + */ + void AppendValue(std::string& buffer, const std::string& value); + public: /** (Re)build the ISUPPORT vector. * Called by the core on boot after all modules have been loaded, and every time when a module is loaded diff --git a/src/server.cpp b/src/server.cpp index 1a92c13a0..1eebdd9e0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -155,6 +155,27 @@ std::string UIDGenerator::GetUID() return current_uid; } +void ISupportManager::AppendValue(std::string& buffer, const std::string& value) +{ + // If this token has no value then we have nothing to do. + if (value.empty()) + return; + + // This function implements value escaping according to the rules of the ISUPPORT draft: + // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03 + buffer.push_back('='); + for (std::string::const_iterator iter = value.begin(); iter != value.end(); ++iter) + { + // The value must be escaped if: + // (1) It is a banned character in an IRC <middle> parameter (NUL, LF, CR, SPACE). + // (2) It has special meaning within an ISUPPORT token (EQUALS, BACKSLASH). + if (*iter == '\0' || *iter == '\n' || *iter == '\r' || *iter == ' ' || *iter == '=' || *iter == '\\') + buffer.append(InspIRCd::Format("\\x%X", *iter)); + else + buffer.push_back(*iter); + } +} + void ISupportManager::Build() { /** @@ -200,10 +221,7 @@ void ISupportManager::Build() { numeric.push(it->first); std::string& token = numeric.GetParams().back(); - - // If this token has a value then append a '=' char after the name and then the value itself - if (!it->second.empty()) - token.append(1, '=').append(it->second); + AppendValue(token, it->second); token_count++; |