summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2017-11-09 10:04:58 +0000
committerPeter Powell <petpow@saberuk.com>2017-11-09 10:30:59 +0000
commit7f7ffef3b4d5dc6242918a48713d6fab96928a80 (patch)
treeab4b7a62f4d9daee8058297a1e69c17b9a1425f4
parentb76ff64daeeb1e1081cff93c611f730e5b1b051e (diff)
Implement support for draft-brocklesby-irc-isupport-03 escapes.
-rw-r--r--include/isupportmanager.h6
-rw-r--r--src/server.cpp26
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++;