Expose 'bdecode limits' settings

This includes:
* Bdecode depth limit
* Bdecode token limit
This commit is contained in:
Chocobo1
2023-07-04 01:30:54 +08:00
parent 66dfe8545d
commit 5a660fc8a9
12 changed files with 98 additions and 13 deletions

View File

@@ -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())));

View File

@@ -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;

View File

@@ -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<lt::torrent_info>(torentInfoRoot, ec);
}

View File

@@ -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());

View File

@@ -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, QString> 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()));

View File

@@ -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);

View File

@@ -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.