Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve relative URLs within RSS article description #21943

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
48 changes: 48 additions & 0 deletions src/gui/rss/rsswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#include "feedlistwidget.h"
#include "ui_rsswidget.h"

void convertRelativePathToAbsolute(QString &html, const QString &basePath);

RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
: GUIApplicationComponent(app, parent)
, m_ui {new Ui::RSSWidget}
Expand Down Expand Up @@ -610,6 +612,52 @@ void RSSWidget::renderArticle(const RSS::Article *article) const

html += u"<pre>" + description + u"</pre>";
}
// Supplement relative path to absolute path

zent1n0 marked this conversation as resolved.
Show resolved Hide resolved
const QUrl url {article->link()};
const QString basePath = url.scheme() + u"://" + url.host();
zent1n0 marked this conversation as resolved.
Show resolved Hide resolved
convertRelativePathToAbsolute(html, basePath);
html += u"</div>";
m_ui->textBrowser->setHtml(html);
}

void convertRelativePathToAbsolute(QString &html, const QString &basePath)
{
QRegularExpression rx;
rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
// href regex
rx.setPattern(
uR"(((<a\s+[^>]*?href|<img\s+[^>]*?src)\s*=\s*["'])((https?|ftp):)?(\/\/[^\/]*)?(\/?[^\/"].*?)(["']))"_s);
zent1n0 marked this conversation as resolved.
Show resolved Hide resolved

QString normalizedBasePath = basePath.endsWith(u'/') ? basePath : basePath + u'/';
QRegularExpressionMatchIterator iter = rx.globalMatch(html);

while (iter.hasNext())
{
const QRegularExpressionMatch match = iter.next();
const QString &scheme = match.captured(4);
const QString &host = match.captured(5);
zent1n0 marked this conversation as resolved.
Show resolved Hide resolved
if (!scheme.isEmpty())
{
if (host.isEmpty())
break; // invalid URL, should never happen

// already absolute path
continue;
}

QString relativePath = match.captured(6);
if (relativePath.startsWith(u'/'))
relativePath = relativePath.mid(1);

if (!host.isEmpty())
normalizedBasePath = u"http:" + host;

const QString &fullMatch = match.captured(0);
const QString &prefix = match.captured(1);
const QString &suffix = match.captured(7);
zent1n0 marked this conversation as resolved.
Show resolved Hide resolved
const QString absolutePath = normalizedBasePath + relativePath;

html.replace(fullMatch, prefix + absolutePath + suffix);
zent1n0 marked this conversation as resolved.
Show resolved Hide resolved
}
}