From 66dfe8545dff47830fdc5c118c7e11d2cad21975 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jul 2023 00:46:42 +0800 Subject: [PATCH 1/2] Expose 'max torrent file size' setting --- src/base/bittorrent/bencoderesumedatastorage.cpp | 6 ++++-- src/base/bittorrent/common.h | 1 - src/base/bittorrent/sessionimpl.cpp | 6 +++--- src/base/bittorrent/torrentinfo.cpp | 4 +++- src/base/preferences.cpp | 13 +++++++++++++ src/base/preferences.h | 2 ++ src/gui/addnewtorrentdialog.cpp | 6 +++--- src/gui/advancedsettings.cpp | 9 +++++++++ src/gui/advancedsettings.h | 5 +++-- src/webui/api/appcontroller.cpp | 5 +++++ src/webui/www/private/views/preferences.html | 10 ++++++++++ 11 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp index b82a3d8f6..922e1f678 100644 --- a/src/base/bittorrent/bencoderesumedatastorage.cpp +++ b/src/base/bittorrent/bencoderesumedatastorage.cpp @@ -44,6 +44,7 @@ #include "base/exceptions.h" #include "base/global.h" #include "base/logger.h" +#include "base/preferences.h" #include "base/profile.h" #include "base/tagset.h" #include "base/utils/fs.h" @@ -134,12 +135,13 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::load(cons const QString idString = id.toString(); const Path fastresumePath = path() / Path(idString + u".fastresume"); const Path torrentFilePath = path() / Path(idString + u".torrent"); + const qint64 torrentSizeLimit = Preferences::instance()->getTorrentFileSizeLimit(); - const auto resumeDataReadResult = Utils::IO::readFile(fastresumePath, MAX_TORRENT_SIZE); + const auto resumeDataReadResult = Utils::IO::readFile(fastresumePath, torrentSizeLimit); if (!resumeDataReadResult) return nonstd::make_unexpected(resumeDataReadResult.error().message); - const auto metadataReadResult = Utils::IO::readFile(torrentFilePath, MAX_TORRENT_SIZE); + const auto metadataReadResult = Utils::IO::readFile(torrentFilePath, torrentSizeLimit); if (!metadataReadResult) { if (metadataReadResult.error().status != Utils::IO::ReadError::NotExist) diff --git a/src/base/bittorrent/common.h b/src/base/bittorrent/common.h index 2c8fe75c7..fa46c0d8d 100644 --- a/src/base/bittorrent/common.h +++ b/src/base/bittorrent/common.h @@ -34,6 +34,5 @@ inline const QString QB_EXT = u".!qB"_s; -inline const int MAX_TORRENT_SIZE = 100 * 1024 * 1024; // 100 MiB inline const int BENCODE_DEPTH_LIMIT = 100; inline const int BENCODE_TOKEN_LIMIT = 10'000'000; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index d3c2304a4..45f26e18b 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -96,7 +96,6 @@ #include "base/version.h" #include "bandwidthscheduler.h" #include "bencoderesumedatastorage.h" -#include "common.h" #include "customstorage.h" #include "dbresumedatastorage.h" #include "downloadpriority.h" @@ -2554,9 +2553,10 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶ if (Net::DownloadManager::hasSupportedScheme(source)) { LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source)); + const auto *pref = Preferences::instance(); // Launch downloader - Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE) - , Preferences::instance()->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished); + Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(pref->getTorrentFileSizeLimit()) + , pref->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished); m_downloadedTorrents[source] = params; return true; } diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index cefc7d770..7d3e440b2 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -42,6 +42,7 @@ #include "base/global.h" #include "base/path.h" +#include "base/preferences.h" #include "base/utils/fs.h" #include "base/utils/io.h" #include "base/utils/misc.h" @@ -104,7 +105,8 @@ nonstd::expected TorrentInfo::loadFromFile(const Path &pat QByteArray data; try { - const auto readResult = Utils::IO::readFile(path, MAX_TORRENT_SIZE); + const qint64 torrentSizeLimit = Preferences::instance()->getTorrentFileSizeLimit(); + const auto readResult = Utils::IO::readFile(path, torrentSizeLimit); if (!readResult) return nonstd::make_unexpected(readResult.error().message); data = readResult.value(); diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 133333a10..be4ef0832 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -304,6 +304,19 @@ void Preferences::setIconsInMenusEnabled(const bool enable) } #endif // Q_OS_MACOS +qint64 Preferences::getTorrentFileSizeLimit() const +{ + return value(u"BitTorrent/TorrentFileSizeLimit"_s, (100 * 1024 * 1024)); +} + +void Preferences::setTorrentFileSizeLimit(const qint64 value) +{ + if (value == getTorrentFileSizeLimit()) + return; + + setValue(u"BitTorrent/TorrentFileSizeLimit"_s, value); +} + bool Preferences::isToolbarDisplayed() const { return value(u"Preferences/General/ToolbarDisplayed"_s, true); diff --git a/src/base/preferences.h b/src/base/preferences.h index b3539b781..7d6c3c1de 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -333,6 +333,8 @@ public: bool iconsInMenusEnabled() const; void setIconsInMenusEnabled(bool enable); #endif // Q_OS_MACOS + qint64 getTorrentFileSizeLimit() const; + void setTorrentFileSizeLimit(qint64 value); // Stuff that don't appear in the Options GUI but are saved // in the same file. diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index e91c84177..840c900ca 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -43,7 +43,6 @@ #include #include -#include "base/bittorrent/common.h" #include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/infohash.h" #include "base/bittorrent/magneturi.h" @@ -489,10 +488,11 @@ void AddNewTorrentDialog::show(const QString &source, const BitTorrent::AddTorre if (Net::DownloadManager::hasSupportedScheme(source)) { + const auto *pref = Preferences::instance(); // Launch downloader Net::DownloadManager::instance()->download( - Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE) - , Preferences::instance()->useProxyForGeneralPurposes() + Net::DownloadRequest(source).limit(pref->getTorrentFileSizeLimit()) + , pref->useProxyForGeneralPurposes() , dlg, &AddNewTorrentDialog::handleDownloadFinished); return; } diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 5de7bac89..882a6abd6 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -75,6 +75,7 @@ namespace NETWORK_IFACE_ADDRESS, // behavior SAVE_RESUME_DATA_INTERVAL, + TORRENT_FILE_SIZE_LIMIT, CONFIRM_RECHECK_TORRENT, RECHECK_COMPLETED, // UI related @@ -244,6 +245,8 @@ void AdvancedSettings::saveAdvancedSettings() const session->setSocketBacklogSize(m_spinBoxSocketBacklogSize.value()); // Save resume data interval session->setSaveResumeDataInterval(m_spinBoxSaveResumeDataInterval.value()); + // .torrent file size limit + pref->setTorrentFileSizeLimit(m_spinBoxTorrentFileSizeLimit.value() * 1024 * 1024); // Outgoing ports session->setOutgoingPortsMin(m_spinBoxOutgoingPortsMin.value()); session->setOutgoingPortsMax(m_spinBoxOutgoingPortsMax.value()); @@ -619,6 +622,12 @@ void AdvancedSettings::loadAdvancedSettings() m_spinBoxSaveResumeDataInterval.setSuffix(tr(" min", " minutes")); m_spinBoxSaveResumeDataInterval.setSpecialValueText(tr("0 (disabled)")); addRow(SAVE_RESUME_DATA_INTERVAL, tr("Save resume data interval [0: disabled]", "How often the fastresume file is saved."), &m_spinBoxSaveResumeDataInterval); + // .torrent file size limit + m_spinBoxTorrentFileSizeLimit.setMinimum(1); + m_spinBoxTorrentFileSizeLimit.setMaximum(std::numeric_limits::max() / 1024 / 1024); + m_spinBoxTorrentFileSizeLimit.setValue(pref->getTorrentFileSizeLimit() / 1024 / 1024); + m_spinBoxTorrentFileSizeLimit.setSuffix(tr(" MiB")); + addRow(TORRENT_FILE_SIZE_LIMIT, tr(".torrent file size limit"), &m_spinBoxTorrentFileSizeLimit); // Outgoing port Min m_spinBoxOutgoingPortsMin.setMinimum(0); m_spinBoxOutgoingPortsMin.setMaximum(65535); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index 2d646f555..fc1a46907 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -67,8 +67,9 @@ private: void loadAdvancedSettings(); template void addRow(int row, const QString &text, T *widget); - QSpinBox m_spinBoxAsyncIOThreads, m_spinBoxFilePoolSize, m_spinBoxCheckingMemUsage, m_spinBoxDiskQueueSize, - m_spinBoxSaveResumeDataInterval, m_spinBoxOutgoingPortsMin, m_spinBoxOutgoingPortsMax, m_spinBoxUPnPLeaseDuration, m_spinBoxPeerToS, + QSpinBox m_spinBoxSaveResumeDataInterval, m_spinBoxTorrentFileSizeLimit, + m_spinBoxAsyncIOThreads, m_spinBoxFilePoolSize, m_spinBoxCheckingMemUsage, m_spinBoxDiskQueueSize, + m_spinBoxOutgoingPortsMin, m_spinBoxOutgoingPortsMax, m_spinBoxUPnPLeaseDuration, m_spinBoxPeerToS, m_spinBoxListRefresh, m_spinBoxTrackerPort, m_spinBoxSendBufferWatermark, m_spinBoxSendBufferLowWatermark, m_spinBoxSendBufferWatermarkFactor, m_spinBoxConnectionSpeed, m_spinBoxSocketSendBufferSize, m_spinBoxSocketReceiveBufferSize, m_spinBoxSocketBacklogSize, m_spinBoxMaxConcurrentHTTPAnnounces, m_spinBoxStopTrackerTimeout, diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index 1bb67cbe7..c718e5232 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -323,6 +323,8 @@ void AppController::preferencesAction() data[u"current_interface_address"_s] = BitTorrent::Session::instance()->networkInterfaceAddress(); // Save resume data interval data[u"save_resume_data_interval"_s] = session->saveResumeDataInterval(); + // .torrent file size limit + data[u"torrent_file_size_limit"_s] = pref->getTorrentFileSizeLimit(); // Recheck completed torrents data[u"recheck_completed_torrents"_s] = pref->recheckTorrentsOnCompletion(); // Refresh interval @@ -853,6 +855,9 @@ void AppController::setPreferencesAction() // Save resume data interval if (hasKey(u"save_resume_data_interval"_s)) session->setSaveResumeDataInterval(it.value().toInt()); + // .torrent file size limit + if (hasKey(u"torrent_file_size_limit"_s)) + pref->setTorrentFileSizeLimit(it.value().toLongLong()); // Recheck completed torrents if (hasKey(u"recheck_completed_torrents"_s)) pref->recheckTorrentsOnCompletion(it.value().toBool()); diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 4c6d22a0c..253cfcfcf 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -977,6 +977,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD   QBT_TR(min)QBT_TR[CONTEXT=OptionsDialog] + + + + + +   QBT_TR(MiB)QBT_TR[CONTEXT=OptionsDialog] + + @@ -2147,6 +2155,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD updateNetworkInterfaces(pref.current_network_interface); updateInterfaceAddresses(pref.current_network_interface, pref.current_interface_address); $('saveResumeDataInterval').setProperty('value', pref.save_resume_data_interval); + $('torrentFileSizeLimit').setProperty('value', (pref.torrent_file_size_limit / 1024 / 1024)); $('recheckTorrentsOnCompletion').setProperty('checked', pref.recheck_completed_torrents); $('refreshInterval').setProperty('value', pref.refresh_interval); $('resolvePeerCountries').setProperty('checked', pref.resolve_peer_countries); @@ -2563,6 +2572,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings.set('current_network_interface', $('networkInterface').getProperty('value')); settings.set('current_interface_address', $('optionalIPAddressToBind').getProperty('value')); settings.set('save_resume_data_interval', $('saveResumeDataInterval').getProperty('value')); + settings.set('torrent_file_size_limit', ($('torrentFileSizeLimit').getProperty('value') * 1024 * 1024)); settings.set('recheck_completed_torrents', $('recheckTorrentsOnCompletion').getProperty('checked')); settings.set('refresh_interval', $('refreshInterval').getProperty('value')); settings.set('resolve_peer_countries', $('resolvePeerCountries').getProperty('checked')); From 5a660fc8a979aa6b97c9059df4216da8b9a80a57 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jul 2023 01:30:54 +0800 Subject: [PATCH 2/2] Expose 'bdecode limits' settings This includes: * Bdecode depth limit * Bdecode token limit --- .../bittorrent/bencoderesumedatastorage.cpp | 8 +++--- src/base/bittorrent/common.h | 3 --- src/base/bittorrent/dbresumedatastorage.cpp | 9 ++++--- src/base/bittorrent/sessionimpl.cpp | 4 +++ src/base/bittorrent/torrentinfo.cpp | 5 ++-- src/base/preferences.cpp | 26 +++++++++++++++++++ src/base/preferences.h | 4 +++ src/gui/advancedsettings.cpp | 18 +++++++++++++ src/gui/advancedsettings.h | 2 +- src/webui/api/appcontroller.cpp | 10 +++++++ src/webui/webapplication.h | 2 +- src/webui/www/private/views/preferences.html | 20 ++++++++++++++ 12 files changed, 98 insertions(+), 13 deletions(-) diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp index 922e1f678..eeb1a8cc0 100644 --- a/src/base/bittorrent/bencoderesumedatastorage.cpp +++ b/src/base/bittorrent/bencoderesumedatastorage.cpp @@ -50,7 +50,6 @@ #include "base/utils/fs.h" #include "base/utils/io.h" #include "base/utils/string.h" -#include "common.h" #include "infohash.h" #include "loadtorrentparams.h" @@ -203,9 +202,11 @@ void BitTorrent::BencodeResumeDataStorage::loadQueue(const Path &queueFilename) BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorrentResumeData(const QByteArray &data, const QByteArray &metadata) const { + const auto *pref = Preferences::instance(); + lt::error_code ec; const lt::bdecode_node resumeDataRoot = lt::bdecode(data, ec - , nullptr, BENCODE_DEPTH_LIMIT, BENCODE_TOKEN_LIMIT); + , nullptr, pref->getBdecodeDepthLimit(), pref->getBdecodeTokenLimit()); if (ec) return nonstd::make_unexpected(tr("Cannot parse resume data: %1").arg(QString::fromStdString(ec.message()))); @@ -272,8 +273,9 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre if (!metadata.isEmpty()) { + const auto *pref = Preferences::instance(); const lt::bdecode_node torentInfoRoot = lt::bdecode(metadata, ec - , nullptr, BENCODE_DEPTH_LIMIT, BENCODE_TOKEN_LIMIT); + , nullptr, pref->getBdecodeDepthLimit(), pref->getBdecodeTokenLimit()); if (ec) return nonstd::make_unexpected(tr("Cannot parse torrent info: %1").arg(QString::fromStdString(ec.message()))); diff --git a/src/base/bittorrent/common.h b/src/base/bittorrent/common.h index fa46c0d8d..fd1e98872 100644 --- a/src/base/bittorrent/common.h +++ b/src/base/bittorrent/common.h @@ -33,6 +33,3 @@ #include "base/global.h" inline const QString QB_EXT = u".!qB"_s; - -inline const int BENCODE_DEPTH_LIMIT = 100; -inline const int BENCODE_TOKEN_LIMIT = 10'000'000; diff --git a/src/base/bittorrent/dbresumedatastorage.cpp b/src/base/bittorrent/dbresumedatastorage.cpp index 86ffac9fd..619ce97b3 100644 --- a/src/base/bittorrent/dbresumedatastorage.cpp +++ b/src/base/bittorrent/dbresumedatastorage.cpp @@ -55,10 +55,10 @@ #include "base/global.h" #include "base/logger.h" #include "base/path.h" +#include "base/preferences.h" #include "base/profile.h" #include "base/utils/fs.h" #include "base/utils/string.h" -#include "common.h" #include "infohash.h" #include "loadtorrentparams.h" @@ -246,10 +246,13 @@ namespace } const QByteArray bencodedResumeData = query.value(DB_COLUMN_RESUMEDATA.name).toByteArray(); + const auto *pref = Preferences::instance(); + const int bdecodeDepthLimit = pref->getBdecodeDepthLimit(); + const int bdecodeTokenLimit = pref->getBdecodeTokenLimit(); lt::error_code ec; const lt::bdecode_node resumeDataRoot = lt::bdecode(bencodedResumeData, ec - , nullptr, BENCODE_DEPTH_LIMIT, BENCODE_TOKEN_LIMIT); + , nullptr, bdecodeDepthLimit, bdecodeTokenLimit); lt::add_torrent_params &p = resumeData.ltAddTorrentParams; @@ -259,7 +262,7 @@ namespace ; !bencodedMetadata.isEmpty()) { const lt::bdecode_node torentInfoRoot = lt::bdecode(bencodedMetadata, ec - , nullptr, BENCODE_DEPTH_LIMIT, BENCODE_TOKEN_LIMIT); + , nullptr, bdecodeDepthLimit, bdecodeTokenLimit); p.ti = std::make_shared(torentInfoRoot, ec); } diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 45f26e18b..5d1c2efd2 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1740,6 +1740,10 @@ lt::settings_pack SessionImpl::loadLTSettings() const settingsPack.set_int(lt::settings_pack::max_out_request_queue, requestQueueSize()); +#ifdef QBT_USES_LIBTORRENT2 + settingsPack.set_int(lt::settings_pack::metadata_token_limit, Preferences::instance()->getBdecodeTokenLimit()); +#endif + settingsPack.set_int(lt::settings_pack::aio_threads, asyncIOThreads()); #ifdef QBT_USES_LIBTORRENT2 settingsPack.set_int(lt::settings_pack::hashing_threads, hashingThreads()); diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index 7d3e440b2..71b82138e 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -46,7 +46,6 @@ #include "base/utils/fs.h" #include "base/utils/io.h" #include "base/utils/misc.h" -#include "common.h" #include "infohash.h" #include "trackerentry.h" @@ -87,9 +86,11 @@ nonstd::expected TorrentInfo::load(const QByteArray &data) { // 2-step construction to overcome default limits of `depth_limit` & `token_limit` which are // used in `torrent_info()` constructor + const auto *pref = Preferences::instance(); + lt::error_code ec; const lt::bdecode_node node = lt::bdecode(data, ec - , nullptr, BENCODE_DEPTH_LIMIT, BENCODE_TOKEN_LIMIT); + , nullptr, pref->getBdecodeDepthLimit(), pref->getBdecodeTokenLimit()); if (ec) return nonstd::make_unexpected(QString::fromStdString(ec.message())); diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index be4ef0832..10cf3234a 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -317,6 +317,32 @@ void Preferences::setTorrentFileSizeLimit(const qint64 value) setValue(u"BitTorrent/TorrentFileSizeLimit"_s, value); } +int Preferences::getBdecodeDepthLimit() const +{ + return value(u"BitTorrent/BdecodeDepthLimit"_s, 100); +} + +void Preferences::setBdecodeDepthLimit(const int value) +{ + if (value == getBdecodeDepthLimit()) + return; + + setValue(u"BitTorrent/BdecodeDepthLimit"_s, value); +} + +int Preferences::getBdecodeTokenLimit() const +{ + return value(u"BitTorrent/BdecodeTokenLimit"_s, 10'000'000); +} + +void Preferences::setBdecodeTokenLimit(const int value) +{ + if (value == getBdecodeTokenLimit()) + return; + + setValue(u"BitTorrent/BdecodeTokenLimit"_s, value); +} + bool Preferences::isToolbarDisplayed() const { return value(u"Preferences/General/ToolbarDisplayed"_s, true); diff --git a/src/base/preferences.h b/src/base/preferences.h index 7d6c3c1de..c65590e4d 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -335,6 +335,10 @@ public: #endif // Q_OS_MACOS qint64 getTorrentFileSizeLimit() const; void setTorrentFileSizeLimit(qint64 value); + int getBdecodeDepthLimit() const; + void setBdecodeDepthLimit(int value); + int getBdecodeTokenLimit() const; + void setBdecodeTokenLimit(int value); // Stuff that don't appear in the Options GUI but are saved // in the same file. diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 882a6abd6..0d0ce6642 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -101,6 +101,8 @@ namespace TRACKER_PORT_FORWARDING, // libtorrent section LIBTORRENT_HEADER, + BDECODE_DEPTH_LIMIT, + BDECODE_TOKEN_LIMIT, ASYNC_IO_THREADS, #ifdef QBT_USES_LIBTORRENT2 HASHING_THREADS, @@ -199,6 +201,10 @@ void AdvancedSettings::saveAdvancedSettings() const #if defined(Q_OS_WIN) app()->setProcessMemoryPriority(m_comboBoxOSMemoryPriority.currentData().value()); #endif + // Bdecode depth limit + pref->setBdecodeDepthLimit(m_spinBoxBdecodeDepthLimit.value()); + // Bdecode token limit + pref->setBdecodeTokenLimit(m_spinBoxBdecodeTokenLimit.value()); // Async IO threads session->setAsyncIOThreads(m_spinBoxAsyncIOThreads.value()); #ifdef QBT_USES_LIBTORRENT2 @@ -464,6 +470,18 @@ void AdvancedSettings::loadAdvancedSettings() + u' ' + makeLink(u"https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-memory_priority_information", u"(?)")) , &m_comboBoxOSMemoryPriority); #endif + // Bdecode depth limit + m_spinBoxBdecodeDepthLimit.setMinimum(0); + m_spinBoxBdecodeDepthLimit.setMaximum(std::numeric_limits::max()); + m_spinBoxBdecodeDepthLimit.setValue(pref->getBdecodeDepthLimit()); + addRow(BDECODE_DEPTH_LIMIT, (tr("Bdecode depth limit") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Bdecoding.html#bdecode()", u"(?)")) + , &m_spinBoxBdecodeDepthLimit); + // Bdecode token limit + m_spinBoxBdecodeTokenLimit.setMinimum(0); + m_spinBoxBdecodeTokenLimit.setMaximum(std::numeric_limits::max()); + m_spinBoxBdecodeTokenLimit.setValue(pref->getBdecodeTokenLimit()); + addRow(BDECODE_TOKEN_LIMIT, (tr("Bdecode token limit") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Bdecoding.html#bdecode()", u"(?)")) + , &m_spinBoxBdecodeTokenLimit); // Async IO threads m_spinBoxAsyncIOThreads.setMinimum(1); m_spinBoxAsyncIOThreads.setMaximum(1024); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index fc1a46907..1cb869e9e 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -67,7 +67,7 @@ private: void loadAdvancedSettings(); template void addRow(int row, const QString &text, T *widget); - QSpinBox m_spinBoxSaveResumeDataInterval, m_spinBoxTorrentFileSizeLimit, + QSpinBox m_spinBoxSaveResumeDataInterval, m_spinBoxTorrentFileSizeLimit, m_spinBoxBdecodeDepthLimit, m_spinBoxBdecodeTokenLimit, m_spinBoxAsyncIOThreads, m_spinBoxFilePoolSize, m_spinBoxCheckingMemUsage, m_spinBoxDiskQueueSize, m_spinBoxOutgoingPortsMin, m_spinBoxOutgoingPortsMax, m_spinBoxUPnPLeaseDuration, m_spinBoxPeerToS, m_spinBoxListRefresh, m_spinBoxTrackerPort, m_spinBoxSendBufferWatermark, m_spinBoxSendBufferLowWatermark, diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index c718e5232..870d696d4 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -335,6 +335,10 @@ void AppController::preferencesAction() data[u"reannounce_when_address_changed"_s] = session->isReannounceWhenAddressChangedEnabled(); // libtorrent preferences + // Bdecode depth limit + data[u"bdecode_depth_limit"_s] = pref->getBdecodeDepthLimit(); + // Bdecode token limit + data[u"bdecode_token_limit"_s] = pref->getBdecodeTokenLimit(); // Async IO threads data[u"async_io_threads"_s] = session->asyncIOThreads(); // Hashing threads @@ -872,6 +876,12 @@ void AppController::setPreferencesAction() session->setReannounceWhenAddressChangedEnabled(it.value().toBool()); // libtorrent preferences + // Bdecode depth limit + if (hasKey(u"bdecode_depth_limit"_s)) + pref->setBdecodeDepthLimit(it.value().toInt()); + // Bdecode token limit + if (hasKey(u"bdecode_token_limit"_s)) + pref->setBdecodeTokenLimit(it.value().toInt()); // Async IO threads if (hasKey(u"async_io_threads"_s)) session->setAsyncIOThreads(it.value().toInt()); diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index 8f68a08a3..364d5ee41 100644 --- a/src/webui/webapplication.h +++ b/src/webui/webapplication.h @@ -52,7 +52,7 @@ #include "base/utils/version.h" #include "api/isessionmanager.h" -inline const Utils::Version<3, 2> API_VERSION {2, 9, 1}; +inline const Utils::Version<3, 2> API_VERSION {2, 9, 2}; class APIController; class AuthController; diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 253cfcfcf..00aa4a59d 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -1046,6 +1046,22 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
QBT_TR(libtorrent Section)QBT_TR[CONTEXT=OptionsDialog] (QBT_TR(Open documentation)QBT_TR[CONTEXT=HttpServer]) + + + + + + + +
+ + + +
+ + + +
@@ -2161,6 +2177,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD $('resolvePeerCountries').setProperty('checked', pref.resolve_peer_countries); $('reannounceWhenAddressChanged').setProperty('checked', pref.reannounce_when_address_changed); // libtorrent section + $('bdecodeDepthLimit').setProperty('value', pref.bdecode_depth_limit); + $('bdecodeTokenLimit').setProperty('value', pref.bdecode_token_limit); $('asyncIOThreads').setProperty('value', pref.async_io_threads); $('hashingThreads').setProperty('value', pref.hashing_threads); $('filePoolSize').setProperty('value', pref.file_pool_size); @@ -2579,6 +2597,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings.set('reannounce_when_address_changed', $('reannounceWhenAddressChanged').getProperty('checked')); // libtorrent section + settings.set('bdecode_depth_limit', $('bdecodeDepthLimit').getProperty('value')); + settings.set('bdecode_token_limit', $('bdecodeTokenLimit').getProperty('value')); settings.set('async_io_threads', $('asyncIOThreads').getProperty('value')); settings.set('hashing_threads', $('hashingThreads').getProperty('value')); settings.set('file_pool_size', $('filePoolSize').getProperty('value'));