diff --git a/client/js/libs/handlebars/ircmessageparser/findNames.js b/client/js/libs/handlebars/ircmessageparser/findNames.js index e72f463a..b6dc5093 100644 --- a/client/js/libs/handlebars/ircmessageparser/findNames.js +++ b/client/js/libs/handlebars/ircmessageparser/findNames.js @@ -1,17 +1,25 @@ "use strict"; +const nickRegExp = /([\w[\]\\`^{|}-]+)/g; + function findNames(text, users) { const result = []; - let index = -1; - users.forEach((nick) => { - index = text.indexOf(nick, ++index); - result.push({ - start: index, - end: index + nick.length, - nick: nick, - }); - }); + // Return early if we don't have any nicknames to find + if (users.length === 0) { + return result; + } + + let match; + while ((match = nickRegExp.exec(text))) { + if (users.indexOf(match[1]) > -1) { + result.push({ + start: match.index, + end: match.index + match[1].length, + nick: match[1], + }); + } + } return result; } diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 40bb04c7..65fb3897 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -4,7 +4,7 @@ const Chan = require("../../models/chan"); const Msg = require("../../models/msg"); const LinkPrefetch = require("./link"); const cleanIrcMessage = require("../../../client/js/libs/handlebars/ircmessageparser/cleanIrcMessage"); -const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]{4,})/g; +const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]+)/g; module.exports = function(irc, network) { const client = this; diff --git a/test/client/js/libs/handlebars/ircmessageparser/findNames.js b/test/client/js/libs/handlebars/ircmessageparser/findNames.js index aefc67e8..3421bdba 100644 --- a/test/client/js/libs/handlebars/ircmessageparser/findNames.js +++ b/test/client/js/libs/handlebars/ircmessageparser/findNames.js @@ -24,6 +24,36 @@ describe("findNames", () => { expect(actual).to.deep.equal(expected); }); + it("should not find nicks as part of a bigger string (issue #1776)", () => { + const input = "you're very unlucky, luck"; + const expected = [ + { + start: 21, + end: 25, + nick: "luck", + }, + ]; + const nicks = ["luck"]; + const actual = findNames(input, nicks); + + expect(actual).to.deep.equal(expected); + }); + + it("should find nicks as short as one character (issue #1885)", () => { + const input = "aaa aa abc a"; + const expected = [ + { + start: 11, + end: 12, + nick: "a", + }, + ]; + const nicks = ["a"]; + const actual = findNames(input, nicks); + + expect(actual).to.deep.equal(expected); + }); + it("should find same nick multiple times", () => { const input = "xPaw xPaw xPaw"; const expected = [