Skip to content

Commit 257d928

Browse files
zent1n0glassez
andauthored
Resolve relative URLs within RSS article description
PR #21943. --------- Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
1 parent 34c8849 commit 257d928

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/gui/rss/rsswidget.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,48 @@
5454
#include "feedlistwidget.h"
5555
#include "ui_rsswidget.h"
5656

57+
namespace
58+
{
59+
void convertRelativeUrlToAbsolute(QString &html, const QString &baseUrl)
60+
{
61+
const QRegularExpression rx {uR"(((<a\s+[^>]*?href|<img\s+[^>]*?src)\s*=\s*["'])((https?|ftp):)?(\/\/[^\/]*)?(\/?[^\/"].*?)(["']))"_s
62+
, QRegularExpression::CaseInsensitiveOption};
63+
64+
const QString normalizedBaseUrl = baseUrl.endsWith(u'/') ? baseUrl : (baseUrl + u'/');
65+
const QUrl url {normalizedBaseUrl};
66+
const QString defaultScheme = url.scheme();
67+
QRegularExpressionMatchIterator iter = rx.globalMatch(html);
68+
69+
while (iter.hasNext())
70+
{
71+
const QRegularExpressionMatch match = iter.next();
72+
const QString scheme = match.captured(4);
73+
const QString host = match.captured(5);
74+
if (!scheme.isEmpty())
75+
{
76+
if (host.isEmpty())
77+
break; // invalid URL, should never happen
78+
79+
// already absolute URL
80+
continue;
81+
}
82+
83+
QString relativePath = match.captured(6);
84+
if (relativePath.startsWith(u'/'))
85+
relativePath = relativePath.mid(1);
86+
87+
const QString absoluteUrl = !host.isEmpty()
88+
? QString(defaultScheme + u':' + host) : (normalizedBaseUrl + relativePath);
89+
const QString fullMatch = match.captured(0);
90+
const QString prefix = match.captured(1);
91+
const QString suffix = match.captured(7);
92+
93+
html.replace(fullMatch, (prefix + absoluteUrl + suffix));
94+
}
95+
}
96+
}
97+
98+
5799
RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
58100
: GUIApplicationComponent(app, parent)
59101
, m_ui {new Ui::RSSWidget}
@@ -605,6 +647,11 @@ void RSSWidget::renderArticle(const RSS::Article *article) const
605647

606648
html += u"<pre>" + description + u"</pre>";
607649
}
650+
651+
// Supplement relative URLs to absolute ones
652+
const QUrl url {article->link()};
653+
const QString baseUrl = url.toString(QUrl::RemovePath | QUrl::RemoveQuery);
654+
convertRelativeUrlToAbsolute(html, baseUrl);
608655
html += u"</div>";
609656
m_ui->textBrowser->setHtml(html);
610657
}

0 commit comments

Comments
 (0)