Don't send markdown links in body

fixes #422
This commit is contained in:
Nicolas Werner 2021-03-15 20:59:18 +01:00
parent 86766b739d
commit 8ca3a8b607
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
3 changed files with 36 additions and 4 deletions

View file

@ -60,6 +60,10 @@ const QRegularExpression url_regex(
// vvvvvv match quote via negative lookahead/lookbehind vv // vvvvvv match quote via negative lookahead/lookbehind vv
// vvvv atomic match url -> fail if there is a " before or after vvv // vvvv atomic match url -> fail if there is a " before or after vvv
R"((?<!["'])(?>((www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'"]+[^!,\.\s<>'"\]\)\:]))(?!["']))"); R"((?<!["'])(?>((www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'"]+[^!,\.\s<>'"\]\)\:]))(?!["']))");
// match any markdown matrix.to link. Capture group 1 is the link name, group 2 is the target.
static const QRegularExpression matrixToMarkdownLink(
R"(\[(.*?)(?<!\\)\]\((https://matrix.to/#/.*?\)))");
static const QRegularExpression matrixToLink(R"(<a href=\"(https://matrix.to/#/.*?)\">(.*?)</a>)");
} }
// Window geometry. // Window geometry.

View file

@ -264,6 +264,9 @@ InputBar::message(QString msg, MarkdownOverride useMarkdown)
useMarkdown == MarkdownOverride::NOT_SPECIFIED) || useMarkdown == MarkdownOverride::NOT_SPECIFIED) ||
useMarkdown == MarkdownOverride::ON) { useMarkdown == MarkdownOverride::ON) {
text.formatted_body = utils::markdownToHtml(msg).toStdString(); text.formatted_body = utils::markdownToHtml(msg).toStdString();
// Remove markdown links by completer
text.body =
msg.trimmed().replace(conf::strings::matrixToMarkdownLink, "\\1").toStdString();
// Don't send formatted_body, when we don't need to // Don't send formatted_body, when we don't need to
if (text.formatted_body.find("<") == std::string::npos) if (text.formatted_body.find("<") == std::string::npos)
@ -326,6 +329,9 @@ InputBar::emote(QString msg)
ChatPage::instance()->userSettings()->markdown()) { ChatPage::instance()->userSettings()->markdown()) {
emote.formatted_body = html.toStdString(); emote.formatted_body = html.toStdString();
emote.format = "org.matrix.custom.html"; emote.format = "org.matrix.custom.html";
// Remove markdown links by completer
emote.body =
msg.trimmed().replace(conf::strings::matrixToMarkdownLink, "\\1").toStdString();
} }
if (!room->reply().isEmpty()) { if (!room->reply().isEmpty()) {

View file

@ -17,6 +17,7 @@
#include <QStandardPaths> #include <QStandardPaths>
#include "ChatPage.h" #include "ChatPage.h"
#include "Config.h"
#include "EventAccessors.h" #include "EventAccessors.h"
#include "Logging.h" #include "Logging.h"
#include "MainWindow.h" #include "MainWindow.h"
@ -1586,10 +1587,31 @@ TimelineModel::setEdit(QString newEdit)
auto msgType = mtx::accessors::msg_type(e); auto msgType = mtx::accessors::msg_type(e);
if (msgType == mtx::events::MessageType::Text || if (msgType == mtx::events::MessageType::Text ||
msgType == mtx::events::MessageType::Notice) { msgType == mtx::events::MessageType::Notice ||
input()->setText(relatedInfo(newEdit).quoted_body); msgType == mtx::events::MessageType::Emote) {
} else if (msgType == mtx::events::MessageType::Emote) { auto relInfo = relatedInfo(newEdit);
input()->setText("/me " + relatedInfo(newEdit).quoted_body); auto editText = relInfo.quoted_body;
if (!relInfo.quoted_formatted_body.isEmpty()) {
auto matches = conf::strings::matrixToLink.globalMatch(
relInfo.quoted_formatted_body);
std::map<QString, QString> reverseNameMapping;
while (matches.hasNext()) {
auto m = matches.next();
reverseNameMapping[m.captured(2)] = m.captured(1);
}
for (const auto &[user, link] : reverseNameMapping) {
// TODO(Nico): html unescape the user name
editText.replace(
user, QStringLiteral("[%1](%2)").arg(user, link));
}
}
if (msgType == mtx::events::MessageType::Emote)
input()->setText("/me " + editText);
else
input()->setText(editText);
} else { } else {
input()->setText(""); input()->setText("");
} }