From d80764c32ff93fee0e1609bc989f37193749c415 Mon Sep 17 00:00:00 2001
From: SyntaxNyah <235356625+SyntaxNyah@users.noreply.github.com>
Date: Tue, 26 May 2026 22:25:31 +0100
Subject: [PATCH] Fix URL corruption caused by HTML escaping
URLs containing & for example discord and stuff were being corrupted because toHtmlEscaped() was called before
URL detection, turning & into amp. inside link hrefs.
This shit has been pissing me off for far too long. This fix detects urls on the raw message then html escapes only the non url text. Applied to server descriptions and OOC chat. Heres a screenshot of me building the client and testing it and yes the discord link downloaded.
---
src/aotextarea.cpp | 15 ++++++++++++++-
src/lobby.cpp | 15 ++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
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);
}