From 0d07699b6d3b5d6d7ca1801003f6ca928ee81166 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Mon, 30 Apr 2018 18:21:25 -0300 Subject: [PATCH 1/2] [FIX] Regression on 0.64.0 was freezing the application when posting some URLs Original PR was https://github.com/RocketChat/Rocket.Chat/pull/10496 --- .../server/functions/sendMessage.js | 37 +++++++------------ packages/rocketchat-markdown/markdown.js | 12 ++++-- .../parser/original/code.js | 4 +- .../rocketchat-markdown/tests/client.tests.js | 6 +-- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/sendMessage.js b/packages/rocketchat-lib/server/functions/sendMessage.js index 585168cfe562..aaafd267eb99 100644 --- a/packages/rocketchat-lib/server/functions/sendMessage.js +++ b/packages/rocketchat-lib/server/functions/sendMessage.js @@ -121,31 +121,22 @@ RocketChat.sendMessage = function(user, message, room, upsert = false) { } if (message.parseUrls !== false) { - const urlRegex = /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g; - const urls = message.msg.match(urlRegex); + message.html = message.msg; + message = RocketChat.Markdown.code(message); + + const urls = message.msg.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g); if (urls) { - // ignoredUrls contain blocks of quotes with urls inside - const ignoredUrls = message.msg.match(/(?:(?:\`{1,3})(?:[\n\r]*?.*?)*?)(([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?)(?:(?:[\n\r]*.*?)*?(?:\`{1,3}))/gm); - if (ignoredUrls) { - ignoredUrls.forEach((url) => { - const shouldBeIgnored = url.match(urlRegex); - if (shouldBeIgnored) { - shouldBeIgnored.forEach((match) => { - const matchIndex = urls.indexOf(match); - urls.splice(matchIndex, 1); - }); - } - }); - } - if (urls) { - // use the Set to remove duplicity, so it doesn't embed the same link twice - message.urls = [...new Set(urls)].map(function(url) { - return { - url - }; - }); - } + message.urls = urls.map(function(url) { + return { + url + }; + }); } + + message = RocketChat.Markdown.mountTokensBack(message, false); + message.msg = message.html; + delete message.html; + delete message.tokens; } message = RocketChat.callbacks.run('beforeSaveMessage', message); diff --git a/packages/rocketchat-markdown/markdown.js b/packages/rocketchat-markdown/markdown.js index 001b39ba57bb..013ddefd2d7f 100644 --- a/packages/rocketchat-markdown/markdown.js +++ b/packages/rocketchat-markdown/markdown.js @@ -10,6 +10,8 @@ import { RocketChat } from 'meteor/rocketchat:lib'; import { marked } from './parser/marked/marked.js'; import { original } from './parser/original/original.js'; +import { code } from './parser/original/code.js'; + const parsers = { original, marked @@ -43,15 +45,19 @@ class MarkdownClass { return parsers['original'](message); } - mountTokensBack(message) { + mountTokensBack(message, useHtml = true) { if (message.tokens && message.tokens.length > 0) { - for (const {token, text} of message.tokens) { - message.html = message.html.replace(token, () => text); // Uses lambda so doesn't need to escape $ + for (const {token, text, noHtml} of message.tokens) { + message.html = message.html.replace(token, () => useHtml ? text : noHtml); // Uses lambda so doesn't need to escape $ } } return message; } + + code(...args) { + return code(...args); + } } const Markdown = new MarkdownClass; diff --git a/packages/rocketchat-markdown/parser/original/code.js b/packages/rocketchat-markdown/parser/original/code.js index e74d271cb317..dc69dcc9f590 100644 --- a/packages/rocketchat-markdown/parser/original/code.js +++ b/packages/rocketchat-markdown/parser/original/code.js @@ -39,7 +39,7 @@ const codeblocks = (message) => { for (let index = 0; index < msgParts.length; index++) { // Verify if this part is code const part = msgParts[index]; - const codeMatch = part.match(/^```(.*[\r\n\ ]?)([\s\S]*?)```+?$/); + const codeMatch = part.match(/^```[\r\n]*(.*[\r\n\ ]?)[\r\n]*([\s\S]*?)```+?$/); if (codeMatch != null) { // Process highlight if this part is code @@ -59,7 +59,7 @@ const codeblocks = (message) => { highlight: true, token, text: `
\`\`\`
${ result.value }
\`\`\`
`, - noHtml: `\`\`\`\n${ s.stripTags(result.value) }\n\`\`\`` + noHtml: codeMatch[0] }); msgParts[index] = token; diff --git a/packages/rocketchat-markdown/tests/client.tests.js b/packages/rocketchat-markdown/tests/client.tests.js index 96c93d98d964..fa376d6bb03d 100644 --- a/packages/rocketchat-markdown/tests/client.tests.js +++ b/packages/rocketchat-markdown/tests/client.tests.js @@ -207,10 +207,10 @@ const inlinecode = { const code = { '```code```': codeWrapper('code', 'clean'), '```code': codeWrapper('code\n', 'stylus'), - '```code\n': codeWrapper('code\n\n', 'stylus'), - '```\ncode\n```': codeWrapper('\ncode\n', 'stylus'), + '```code\n': codeWrapper('code\n', 'stylus'), + '```\ncode\n```': codeWrapper('code\n', 'stylus'), '```code\n```': codeWrapper('code\n', 'stylus'), - '```\ncode```': codeWrapper('\ncode', 'clean'), + '```\ncode```': codeWrapper('code', 'clean'), '```javascript\nvar a = \'log\';\nconsole.log(a);```': codeWrapper('var a = \'log\';\nconsole.log(a);', 'javascript'), '```*code*```': codeWrapper('*code*', 'armasm'), '```**code**```': codeWrapper('**code**', 'armasm'), From 0284d73bd468463777a516b1949b2a57d39c85fc Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Mon, 30 Apr 2018 22:43:18 -0300 Subject: [PATCH 2/2] Look for URLs on parsed markdown HTML --- packages/rocketchat-lib/server/functions/sendMessage.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/sendMessage.js b/packages/rocketchat-lib/server/functions/sendMessage.js index aaafd267eb99..89c58881ac17 100644 --- a/packages/rocketchat-lib/server/functions/sendMessage.js +++ b/packages/rocketchat-lib/server/functions/sendMessage.js @@ -124,13 +124,9 @@ RocketChat.sendMessage = function(user, message, room, upsert = false) { message.html = message.msg; message = RocketChat.Markdown.code(message); - const urls = message.msg.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g); + const urls = message.html.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g); if (urls) { - message.urls = urls.map(function(url) { - return { - url - }; - }); + message.urls = urls.map((url) => ({ url })); } message = RocketChat.Markdown.mountTokensBack(message, false);