Bug 1644024 - Properly escape HTML in topics. r=khushil a=wsmwk
authorPatrick Cloke <clokep@gmail.com>
Sat, 27 Jun 2020 11:54:03 +0300
changeset 39487 33b9e7a5703975410b1a144a24811eae6b910aea
parent 39486 524b05c44acdd21378e899e949a1bbfb0f08d74e
child 39488 dcc756af25ee9422492b980b5933b16172b00c7b
push id402
push userclokep@gmail.com
push dateMon, 29 Jun 2020 20:48:04 +0000
reviewerskhushil, wsmwk
bugs1644024
Bug 1644024 - Properly escape HTML in topics. r=khushil a=wsmwk
chat/modules/jsProtoHelper.jsm
chat/protocols/irc/ircUtils.jsm
--- a/chat/modules/jsProtoHelper.jsm
+++ b/chat/modules/jsProtoHelper.jsm
@@ -26,16 +26,21 @@ const { Services } = ChromeUtils.import(
 const { ClassInfo } = ChromeUtils.import(
   "resource:///modules/imXPCOMUtils.jsm"
 );
 
 XPCOMUtils.defineLazyGetter(this, "_", () =>
   l10nHelper("chrome://chat/locale/conversations.properties")
 );
 
+XPCOMUtils.defineLazyGetter(this, "TXTToHTML", function() {
+  let cs = Cc["@mozilla.org/txttohtmlconv;1"].getService(Ci.mozITXTToHTMLConv);
+  return aTXT => cs.scanTXT(aTXT, cs.kEntities);
+});
+
 var GenericAccountPrototype = {
   __proto__: ClassInfo("prplIAccount", "generic account object"),
   get wrappedJSObject() {
     return this;
   },
   _init(aProtocol, aImAccount) {
     this.protocol = aProtocol;
     this.imAccount = aImAccount;
@@ -759,16 +764,25 @@ var GenericConvChatPrototype = {
     return this._topic;
   },
   get topicSettable() {
     return false;
   },
   get topicSetter() {
     return this._topicSetter;
   },
+  /**
+   * Set the topic of a conversation.
+   *
+   * @param {string} aTopic - The new topic. If an update message is sent to
+   *   the conversation, this will be HTML escaped before being sent.
+   * @param {string} aTopicSetter - The user who last modified the topic.
+   * @param {string} aQuiet - If false, a message notifying about the topic
+   *   change will be sent to the conversation.
+   */
   setTopic(aTopic, aTopicSetter, aQuiet) {
     // Only change the topic if the topic and/or topic setter has changed.
     if (
       this._topic == aTopic &&
       (!this._topicSetter || this._topicSetter == aTopicSetter)
     ) {
       return;
     }
@@ -781,24 +795,24 @@ var GenericConvChatPrototype = {
     if (aQuiet) {
       return;
     }
 
     // Send the topic as a message.
     let message;
     if (aTopicSetter) {
       if (aTopic) {
-        message = _("topicChanged", aTopicSetter, aTopic);
+        message = _("topicChanged", aTopicSetter, TXTToHTML(aTopic));
       } else {
         message = _("topicCleared", aTopicSetter);
       }
     } else {
       aTopicSetter = null;
       if (aTopic) {
-        message = _("topicSet", this.name, aTopic);
+        message = _("topicSet", this.name, TXTToHTML(aTopic));
       } else {
         message = _("topicNotSet", this.name);
       }
     }
     this.writeMessage(aTopicSetter, message, { system: true });
   },
 
   get nick() {
--- a/chat/protocols/irc/ircUtils.jsm
+++ b/chat/protocols/irc/ircUtils.jsm
@@ -50,17 +50,17 @@ var CTCP_TAGS = {
 };
 
 // Generate an expression that will search for any of the control characters.
 var CTCP_TAGS_EXP = new RegExp("[" + Object.keys(CTCP_TAGS).join("") + "]");
 
 // Remove all CTCP formatting characters.
 function ctcpFormatToText(aString) {
   let next,
-    input = TXTToHTML(aString),
+    input = aString,
     output = "",
     length;
 
   while ((next = CTCP_TAGS_EXP.exec(input))) {
     if (next.index > 0) {
       output += input.substr(0, next.index);
     }
     // We assume one character will be stripped.