diff --git a/src/aotextarea.cpp b/src/aotextarea.cpp index 08885da80..32f61dbb2 100644 --- a/src/aotextarea.cpp +++ b/src/aotextarea.cpp @@ -27,7 +27,20 @@ void AOTextArea::addMessage(QString name, QString message, QString nameColor, QS message += " "; } - QString result = message.toHtmlEscaped().replace("\n", "
").replace(url_parser_regex, "\\1"); + // Detect URLs before HTML escaping to prevent & from becoming & in links + QString result; + int lastEnd = 0; + QRegularExpressionMatchIterator it = url_parser_regex.globalMatch(message); + while (it.hasNext()) + { + QRegularExpressionMatch match = it.next(); + result += message.mid(lastEnd, match.capturedStart() - lastEnd).toHtmlEscaped(); + QString url = match.captured(1); + result += "" + url.toHtmlEscaped() + ""; + lastEnd = match.capturedEnd(); + } + result += message.mid(lastEnd).toHtmlEscaped(); + result.replace("\n", "
"); if (!messageColor.isEmpty()) { diff --git a/src/lobby.cpp b/src/lobby.cpp index c62f3e06f..c684c4071 100644 --- a/src/lobby.cpp +++ b/src/lobby.cpp @@ -595,7 +595,20 @@ void Lobby::set_server_description(const QString &server_description) { ui_server_description_text->clear(); static QRegularExpression regexp_links("\\b(https?://\\S+\\.\\S+)\\b"); - QString result = server_description.toHtmlEscaped().replace("\n", "
").replace(regexp_links, "\\1"); + // Detect URLs before HTML escaping to prevent & from becoming & in links + QString result; + int lastEnd = 0; + QRegularExpressionMatchIterator it = regexp_links.globalMatch(server_description); + while (it.hasNext()) + { + QRegularExpressionMatch match = it.next(); + result += server_description.mid(lastEnd, match.capturedStart() - lastEnd).toHtmlEscaped(); + QString url = match.captured(1); + result += "" + url.toHtmlEscaped() + ""; + lastEnd = match.capturedEnd(); + } + result += server_description.mid(lastEnd).toHtmlEscaped(); + result.replace("\n", "
"); ui_server_description_text->insertHtml(result); }