mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-05 20:51:25 -07:00
Merge private branch for an RSS security fix
Some checks failed
CI - File health / Check (push) Has been cancelled
CI - macOS / Build (push) Has been cancelled
CI - Python / Check (push) Has been cancelled
CI - Ubuntu / Build (push) Has been cancelled
CI - WebUI / Check (push) Has been cancelled
CI - Windows / Build (push) Has been cancelled
Some checks failed
CI - File health / Check (push) Has been cancelled
CI - macOS / Build (push) Has been cancelled
CI - Python / Check (push) Has been cancelled
CI - Ubuntu / Build (push) Has been cancelled
CI - WebUI / Check (push) Has been cancelled
CI - Windows / Build (push) Has been cancelled
Reported responsibly by Michael Lappas (@lappas-m)
This commit is contained in:
commit
4f94eac235
4 changed files with 96 additions and 20 deletions
|
@ -48,16 +48,16 @@ const QString Article::KeyIsRead = u"isRead"_s;
|
||||||
|
|
||||||
Article::Article(Feed *feed, const QVariantHash &varHash)
|
Article::Article(Feed *feed, const QVariantHash &varHash)
|
||||||
: QObject(feed)
|
: QObject(feed)
|
||||||
, m_feed(feed)
|
, m_feed {feed}
|
||||||
, m_guid(varHash.value(KeyId).toString())
|
, m_guid {varHash.value(KeyId).toString()}
|
||||||
, m_date(varHash.value(KeyDate).toDateTime())
|
, m_date {varHash.value(KeyDate).toDateTime()}
|
||||||
, m_title(varHash.value(KeyTitle).toString())
|
, m_title {varHash.value(KeyTitle).toString()}
|
||||||
, m_author(varHash.value(KeyAuthor).toString())
|
, m_author {varHash.value(KeyAuthor).toString()}
|
||||||
, m_description(varHash.value(KeyDescription).toString())
|
, m_description {varHash.value(KeyDescription).toString()}
|
||||||
, m_torrentURL(varHash.value(KeyTorrentURL).toString())
|
, m_torrentURL {varHash.value(KeyTorrentURL).toString()}
|
||||||
, m_link(varHash.value(KeyLink).toString())
|
, m_link {varHash.value(KeyLink).toString()}
|
||||||
, m_isRead(varHash.value(KeyIsRead, false).toBool())
|
, m_isRead {varHash.value(KeyIsRead, false).toBool()}
|
||||||
, m_data(varHash)
|
, m_data {varHash}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
|
#include "base/logger.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/rss/rss_article.h"
|
#include "base/rss/rss_article.h"
|
||||||
|
@ -433,16 +434,52 @@ void RSSWidget::downloadSelectedTorrents()
|
||||||
// open the url of the selected RSS articles in the Web browser
|
// open the url of the selected RSS articles in the Web browser
|
||||||
void RSSWidget::openSelectedArticlesUrls()
|
void RSSWidget::openSelectedArticlesUrls()
|
||||||
{
|
{
|
||||||
|
qsizetype emptyLinkCount = 0;
|
||||||
|
qsizetype badLinkCount = 0;
|
||||||
|
QString articleTitle;
|
||||||
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
|
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
|
||||||
{
|
{
|
||||||
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
|
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
|
||||||
Q_ASSERT(article);
|
Q_ASSERT(article);
|
||||||
|
|
||||||
// Mark as read
|
|
||||||
article->markAsRead();
|
article->markAsRead();
|
||||||
|
|
||||||
if (!article->link().isEmpty())
|
const QString articleLink = article->link();
|
||||||
QDesktopServices::openUrl(QUrl(article->link()));
|
const QUrl articleLinkURL {articleLink};
|
||||||
|
if (articleLinkURL.isEmpty()) [[unlikely]]
|
||||||
|
{
|
||||||
|
if (articleTitle.isEmpty())
|
||||||
|
articleTitle = article->title();
|
||||||
|
++emptyLinkCount;
|
||||||
|
}
|
||||||
|
else if (articleLinkURL.isLocalFile()) [[unlikely]]
|
||||||
|
{
|
||||||
|
if (badLinkCount == 0)
|
||||||
|
articleTitle = article->title();
|
||||||
|
++badLinkCount;
|
||||||
|
|
||||||
|
LogMsg(tr("Blocked opening RSS article URL. URL pointing to local file might be malicious behaviour. Article: \"%1\". URL: \"%2\".")
|
||||||
|
.arg(article->title(), articleLink), Log::WARNING);
|
||||||
|
}
|
||||||
|
else [[likely]]
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(articleLinkURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (badLinkCount > 0)
|
||||||
|
{
|
||||||
|
QString message = tr("Blocked opening RSS article URL. The following article URL is pointing to local file and it may be malicious behaviour:\n%1").arg(articleTitle);
|
||||||
|
if (badLinkCount > 1)
|
||||||
|
message.append(u"\n" + tr("There are %1 more articles with the same issue.").arg(badLinkCount - 1));
|
||||||
|
QMessageBox::warning(this, u"qBittorrent"_s, message, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
else if (emptyLinkCount > 0)
|
||||||
|
{
|
||||||
|
QString message = tr("The following article has no news URL provided:\n%1").arg(articleTitle);
|
||||||
|
if (emptyLinkCount > 1)
|
||||||
|
message.append(u"\n" + tr("There are %1 more articles with the same issue.").arg(emptyLinkCount - 1));
|
||||||
|
QMessageBox::warning(this, u"qBittorrent"_s, message, QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,12 @@
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include "base/logger.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/search/searchdownloadhandler.h"
|
#include "base/search/searchdownloadhandler.h"
|
||||||
#include "base/search/searchhandler.h"
|
#include "base/search/searchhandler.h"
|
||||||
|
@ -319,15 +321,52 @@ void SearchJobWidget::downloadTorrents(const AddTorrentOption option)
|
||||||
downloadTorrent(rowIndex, option);
|
downloadTorrent(rowIndex, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchJobWidget::openTorrentPages() const
|
void SearchJobWidget::openTorrentPages()
|
||||||
{
|
{
|
||||||
const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
|
const QModelIndexList rows = m_ui->resultsBrowser->selectionModel()->selectedRows();
|
||||||
|
qsizetype emptyLinkCount = 0;
|
||||||
|
qsizetype badLinkCount = 0;
|
||||||
|
QString warningEntryName;
|
||||||
for (const QModelIndex &rowIndex : rows)
|
for (const QModelIndex &rowIndex : rows)
|
||||||
{
|
{
|
||||||
const QString descrLink = m_proxyModel->data(
|
const QString entryName = m_proxyModel->index(rowIndex.row(), SearchSortModel::NAME).data().toString();
|
||||||
m_proxyModel->index(rowIndex.row(), SearchSortModel::DESC_LINK)).toString();
|
const QString descrLink = m_proxyModel->index(rowIndex.row(), SearchSortModel::DESC_LINK).data().toString();
|
||||||
if (!descrLink.isEmpty())
|
|
||||||
QDesktopServices::openUrl(QUrl::fromEncoded(descrLink.toUtf8()));
|
const QUrl descrLinkURL {descrLink};
|
||||||
|
if (descrLinkURL.isEmpty()) [[unlikely]]
|
||||||
|
{
|
||||||
|
if (warningEntryName.isEmpty())
|
||||||
|
warningEntryName = entryName;
|
||||||
|
++emptyLinkCount;
|
||||||
|
}
|
||||||
|
else if (descrLinkURL.isLocalFile()) [[unlikely]]
|
||||||
|
{
|
||||||
|
if (badLinkCount == 0)
|
||||||
|
warningEntryName = entryName;
|
||||||
|
++badLinkCount;
|
||||||
|
|
||||||
|
LogMsg(tr("Blocked opening search result description page URL. URL pointing to local file might be malicious behaviour. Name: \"%1\". URL: \"%2\".")
|
||||||
|
.arg(entryName, descrLink), Log::WARNING);
|
||||||
|
}
|
||||||
|
else [[likely]]
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(descrLinkURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (badLinkCount > 0)
|
||||||
|
{
|
||||||
|
QString message = tr("Blocked opening search result description page URL. The following result URL is pointing to local file and it may be malicious behaviour:\n%1").arg(warningEntryName);
|
||||||
|
if (badLinkCount > 1)
|
||||||
|
message.append(u"\n" + tr("There are %1 more results with the same issue.").arg(badLinkCount - 1));
|
||||||
|
QMessageBox::warning(this, u"qBittorrent"_s, message, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
else if (emptyLinkCount > 0)
|
||||||
|
{
|
||||||
|
QString message = tr("Entry \"%1\" has no description page URL provided.").arg(warningEntryName);
|
||||||
|
if (emptyLinkCount > 1)
|
||||||
|
message.append(u"\n" + tr("There are %1 more entries with the same issue.").arg(emptyLinkCount - 1));
|
||||||
|
QMessageBox::warning(this, u"qBittorrent"_s, message, QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ private:
|
||||||
void onUIThemeChanged();
|
void onUIThemeChanged();
|
||||||
|
|
||||||
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
|
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
|
||||||
void openTorrentPages() const;
|
void openTorrentPages();
|
||||||
void copyTorrentURLs() const;
|
void copyTorrentURLs() const;
|
||||||
void copyTorrentDownloadLinks() const;
|
void copyTorrentDownloadLinks() const;
|
||||||
void copyTorrentNames() const;
|
void copyTorrentNames() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue