diff --git a/lib/channel/chat.js b/lib/channel/chat.js
index 24ebc299..4bf13d1e 100644
--- a/lib/channel/chat.js
+++ b/lib/channel/chat.js
@@ -8,6 +8,9 @@ var url = require("url");
const SHADOW_TAG = "[shadow]";
const LINK = /(\w+:\/\/(?:[^:\/\[\]\s]+|\[[0-9a-f:]+\])(?::\d+)?(?:\/[^\/\s]*)*)/ig;
+const LINK_PLACEHOLDER = '\ueeee';
+const LINK_PLACEHOLDER_RE = /\ueeee/g;
+
const TYPE_CHAT = {
msg: "string",
meta: "object,optional"
@@ -304,34 +307,31 @@ ChatModule.prototype.formatMessage = function (username, data) {
return obj;
};
-const link = /(\w+:\/\/(?:[^:\/\[\]\s]+|\[[0-9a-f:]+\])(?::\d+)?(?:\/[^\/\s]*)*)/ig;
ChatModule.prototype.filterMessage = function (msg) {
var filters = this.channel.modules.filters.filters;
var chan = this.channel;
- var parts = msg.split(link);
var convertLinks = this.channel.modules.options.get("enable_link_regex");
+ var links = msg.match(LINK);
+ var intermediate = msg.replace(LINK, LINK_PLACEHOLDER);
- for (var j = 0; j < parts.length; j++) {
- /* substring is a URL */
- if (convertLinks && parts[j].match(link)) {
- var original = parts[j];
- parts[j] = filters.filter(parts[j], true);
-
- /* no filters changed the URL, apply link filter */
- if (parts[j] === original) {
- parts[j] = url.format(url.parse(parts[j]));
- parts[j] = parts[j].replace(link, "$1");
- }
-
- } else {
- /* substring is not a URL */
- parts[j] = filters.filter(parts[j], false);
+ var result = filters.filter(intermediate, false);
+ result = result.replace(LINK_PLACEHOLDER_RE, function () {
+ var link = links.shift();
+ if (!link) {
+ return '';
}
- }
- msg = parts.join("");
- /* Anti-XSS */
- return XSS.sanitizeHTML(msg);
+ var filtered = filters.filter(link, true);
+ if (filtered !== link) {
+ return filtered;
+ } else if (convertLinks) {
+ return "" + link + "";
+ } else {
+ return link;
+ }
+ });
+
+ return XSS.sanitizeHTML(result);
};
ChatModule.prototype.sendModMessage = function (msg, minrank) {