]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Implement support for draft-brocklesby-irc-isupport-03 escapes.
authorPeter Powell <petpow@saberuk.com>
Thu, 9 Nov 2017 10:04:58 +0000 (10:04 +0000)
committerPeter Powell <petpow@saberuk.com>
Thu, 9 Nov 2017 10:30:59 +0000 (10:30 +0000)
include/isupportmanager.h
src/server.cpp

index 3a0df78f940f698c8bd58c799465831e2464aa10..e5eeb599e7767d450103f777ef019bff551ef835 100644 (file)
@@ -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
index 1a92c13a0dbe44eaf6538717ec0290aba0bc894c..1eebdd9e043ad93d02ff612bcb1be01e04b55aef 100644 (file)
@@ -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++;