From ed21f775c9fc2361c1c3daaf6d96b4fe53117b1e Mon Sep 17 00:00:00 2001 From: "Stiliyan Tonev (Bark)" Date: Fri, 10 Jan 2025 09:56:21 +0200 Subject: [PATCH 1/3] fix: Add check for Content-Type when downloading tracker list. Check if the URL from where we are downloading the trackers returns `Content-Type` as `text`. Otherwise consider it might be a non-usable format for this functionality (html,xml,etc.ect.) --- src/base/net/downloadhandlerimpl.cpp | 1 + src/base/net/downloadmanager.h | 1 + src/gui/trackersadditiondialog.cpp | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/src/base/net/downloadhandlerimpl.cpp b/src/base/net/downloadhandlerimpl.cpp index 370347946c1f..61a516088473 100644 --- a/src/base/net/downloadhandlerimpl.cpp +++ b/src/base/net/downloadhandlerimpl.cpp @@ -143,6 +143,7 @@ void Net::DownloadHandlerImpl::processFinishedDownload() #else m_result.data = m_reply->readAll(); #endif + m_result.contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); if (m_downloadRequest.saveToFile()) { diff --git a/src/base/net/downloadmanager.h b/src/base/net/downloadmanager.h index 8f74c2f9d135..a13768e9d534 100644 --- a/src/base/net/downloadmanager.h +++ b/src/base/net/downloadmanager.h @@ -107,6 +107,7 @@ namespace Net QByteArray data; Path filePath; QString magnetURI; + QString contentType; }; class DownloadHandler : public QObject diff --git a/src/gui/trackersadditiondialog.cpp b/src/gui/trackersadditiondialog.cpp index 0014d5a5521b..4c93aacbc62b 100644 --- a/src/gui/trackersadditiondialog.cpp +++ b/src/gui/trackersadditiondialog.cpp @@ -109,6 +109,13 @@ void TrackersAdditionDialog::onTorrentListDownloadFinished(const Net::DownloadRe m_ui->downloadButton->setEnabled(true); setCursor(Qt::ArrowCursor); + if (!result.contentType.contains(u"text/plain"_s, Qt::CaseInsensitive)) + { + QMessageBox::warning(this, tr("Download trackers list error") + , tr("The content type of the downloaded file is not plain text. Content-Type: \"%1\"").arg(result.contentType)); + return; + } + if (result.status != Net::DownloadStatus::Success) { QMessageBox::warning(this, tr("Download trackers list error") From ac95b0c668928a9c01ba16abf6ca30b2cbffb5b9 Mon Sep 17 00:00:00 2001 From: "Stiliyan Tonev (Bark)" Date: Fri, 10 Jan 2025 13:58:14 +0200 Subject: [PATCH 2/3] Check header after request succeeds, check if added trackers are valid URL\'s --- src/gui/trackersadditiondialog.cpp | 31 +++++++++++++++++++++++++----- src/gui/trackersadditiondialog.h | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gui/trackersadditiondialog.cpp b/src/gui/trackersadditiondialog.cpp index 4c93aacbc62b..9403edf3b535 100644 --- a/src/gui/trackersadditiondialog.cpp +++ b/src/gui/trackersadditiondialog.cpp @@ -74,14 +74,35 @@ TrackersAdditionDialog::~TrackersAdditionDialog() delete m_ui; } +int TrackersAdditionDialog::isValidEndpoint(const QStringView &endpoint) const +{ + if (endpoint.isEmpty()) + return 0; + QUrl url(endpoint.toString()); + if (!url.isValid()) + return 0; + if (url.scheme().isEmpty()) + return 0; + if (url.host().isEmpty()) + return 0; + return 1; +} + void TrackersAdditionDialog::onAccepted() const { const QList currentTrackers = m_torrent->trackers(); const int baseTier = !currentTrackers.isEmpty() ? (currentTrackers.last().tier + 1) : 0; QList entries = BitTorrent::parseTrackerEntries(m_ui->textEditTrackersList->toPlainText()); - for (BitTorrent::TrackerEntry &entry : entries) + for (BitTorrent::TrackerEntry &entry : entries) { + auto isValid = isValidEndpoint(entry.url); + if (!isValid) + { + QMessageBox::warning(const_cast(this), tr("Invalid tracker URL"), tr("The tracker URL \"%1\" is invalid").arg(entry.url)); + return; + } entry.tier = Utils::Number::clampingAdd(entry.tier, baseTier); + } m_torrent->addTrackers(entries); } @@ -109,17 +130,17 @@ void TrackersAdditionDialog::onTorrentListDownloadFinished(const Net::DownloadRe m_ui->downloadButton->setEnabled(true); setCursor(Qt::ArrowCursor); - if (!result.contentType.contains(u"text/plain"_s, Qt::CaseInsensitive)) + if (result.status != Net::DownloadStatus::Success) { QMessageBox::warning(this, tr("Download trackers list error") - , tr("The content type of the downloaded file is not plain text. Content-Type: \"%1\"").arg(result.contentType)); + , tr("Error occurred when downloading the trackers list. Reason: \"%1\"").arg(result.errorString)); return; } - if (result.status != Net::DownloadStatus::Success) + if (!result.contentType.contains(u"text/plain"_s, Qt::CaseInsensitive)) { QMessageBox::warning(this, tr("Download trackers list error") - , tr("Error occurred when downloading the trackers list. Reason: \"%1\"").arg(result.errorString)); + , tr("The content type of the downloaded file is not plain text. Content-Type: \"%1\"").arg(result.contentType)); return; } diff --git a/src/gui/trackersadditiondialog.h b/src/gui/trackersadditiondialog.h index 0dc658cffef7..893379f684f8 100644 --- a/src/gui/trackersadditiondialog.h +++ b/src/gui/trackersadditiondialog.h @@ -65,6 +65,7 @@ private slots: private: void saveSettings(); void loadSettings(); + int isValidEndpoint(const QStringView &endpoint) const; Ui::TrackersAdditionDialog *m_ui = nullptr; BitTorrent::Torrent *const m_torrent = nullptr; From 1f1bc457799b2a60f59151d2b9082c727ef00ee5 Mon Sep 17 00:00:00 2001 From: "Stiliyan Tonev (Bark)" Date: Mon, 13 Jan 2025 16:12:42 +0200 Subject: [PATCH 3/3] Add check to Bittorrent tab in preferences too. --- src/gui/optionsdialog.cpp | 35 +++++++++++++++++++++++++++++++++++ src/gui/optionsdialog.h | 3 +++ 2 files changed, 38 insertions(+) diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index 676612146589..1e49b87a4b39 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -83,6 +83,7 @@ #include "watchedfolderoptionsdialog.h" #include "watchedfoldersmodel.h" #include "webui/webui.h" +#include "base/net/downloadmanager.h" #ifndef DISABLE_WEBUI #include "base/net/dnsupdater.h" @@ -1227,8 +1228,42 @@ void OptionsDialog::saveBittorrentTabOptions() const session->setAddTrackersEnabled(m_ui->checkEnableAddTrackers->isChecked()); session->setAdditionalTrackers(m_ui->textTrackers->toPlainText()); + auto enabledAddTrackers = m_ui->checkAddTrackersFromURL->isChecked(); + auto url = m_ui->textTrackersURL->text(); + if (!url.isEmpty() && enabledAddTrackers) + { + Net::DownloadManager::instance()->download(url, Preferences::instance()->useProxyForGeneralPurposes() + , this, &OptionsDialog::onAddTrackersDownload); + } + else + { + session->setAddTrackersFromURLEnabled(enabledAddTrackers); + session->setAdditionalTrackersURL(url); + } +} + +void OptionsDialog::onAddTrackersDownload(const Net::DownloadResult &result) +{ + if (result.status != Net::DownloadStatus::Success) + { + QMessageBox::warning(this, tr("Download trackers list error") + , tr("Error occurred when downloading the trackers list. Reason: \"%1\"").arg(result.errorString)); + return; + } + + if (!result.contentType.contains(u"text/plain"_s, Qt::CaseInsensitive)) + { + QMessageBox::warning(this, tr("Download trackers list error") + , tr("The content type of the downloaded file is not plain text. Content-Type: \"%1\"").arg(result.contentType)); + return; + } + + auto *session = BitTorrent::Session::instance(); + session->setAddTrackersFromURLEnabled(m_ui->checkAddTrackersFromURL->isChecked()); session->setAdditionalTrackersURL(m_ui->textTrackersURL->text()); + + return; } void OptionsDialog::loadRSSTabOptions() diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h index 534ca4078ef8..28ae97bda4c7 100644 --- a/src/gui/optionsdialog.h +++ b/src/gui/optionsdialog.h @@ -34,6 +34,7 @@ #include "base/pathfwd.h" #include "base/settingvalue.h" #include "guiapplicationcomponent.h" +#include "base/net/downloadmanager.h" class QListWidgetItem; @@ -136,6 +137,8 @@ private slots: void loadRSSTabOptions(); void saveRSSTabOptions() const; + void onAddTrackersDownload(const Net::DownloadResult &result); + #ifndef DISABLE_WEBUI void loadWebUITabOptions(); void saveWebUITabOptions() const;