diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp index b82a3d8f6..eeb1a8cc0 100644 --- a/src/base/bittorrent/bencoderesumedatastorage.cpp +++ b/src/base/bittorrent/bencoderesumedatastorage.cpp @@ -44,12 +44,12 @@ #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" #include "base/utils/io.h" #include "base/utils/string.h" -#include "common.h" #include "infohash.h" #include "loadtorrentparams.h" @@ -134,12 +134,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) @@ -201,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()))); @@ -270,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 2c8fe75c7..fd1e98872 100644 --- a/src/base/bittorrent/common.h +++ b/src/base/bittorrent/common.h @@ -33,7 +33,3 @@ #include "base/global.h" 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/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 bf31a5704..2e5aec040 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" @@ -1742,6 +1741,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()); @@ -2555,9 +2558,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..71b82138e 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -42,10 +42,10 @@ #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" -#include "common.h" #include "infohash.h" #include "trackerentry.h" @@ -86,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())); @@ -104,7 +106,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 48a128ed7..331983640 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -304,6 +304,45 @@ 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); +} + +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 5bb0950ab..9f17eabb5 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -335,6 +335,12 @@ public: bool iconsInMenusEnabled() const; void setIconsInMenusEnabled(bool enable); #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/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 4b092be34..f811c855b 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..0d0ce6642 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 @@ -100,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, @@ -198,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 @@ -244,6 +251,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()); @@ -461,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); @@ -619,6 +640,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..1cb869e9e 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_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, 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 c00508ba6..7c6096578 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -326,6 +326,8 @@ void AppController::preferencesAction() data[u"current_interface_address"_s] = session->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 @@ -336,6 +338,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 @@ -859,6 +865,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()); @@ -873,6 +882,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 fb0374f68..8997f756c 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] + + @@ -1038,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]) + + + + + + + +
+ + + +
+ + + +
@@ -2151,11 +2175,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD updateNetworkInterfaces(pref.current_network_interface, pref.current_interface_name); 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); $('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); @@ -2567,12 +2594,15 @@ 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')); 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'));