mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-29 13:58:51 +03:00
Fix loading very large torrents. Closes #8449.
`torrent_info` constructor has default limits that can't be changed via parameters, so we handle the loading process manually and explicitly specifiy the limits to `bdecode()`. The token_limit is also changed to 10000000.
This commit is contained in:
parent
edef85fa3e
commit
f5fc2d52b8
2 changed files with 46 additions and 5 deletions
|
@ -76,13 +76,51 @@ TorrentInfo TorrentInfo::load(const QByteArray &data, QString *error) noexcept
|
||||||
|
|
||||||
TorrentInfo TorrentInfo::loadFromFile(const QString &path, QString *error) noexcept
|
TorrentInfo TorrentInfo::loadFromFile(const QString &path, QString *error) noexcept
|
||||||
{
|
{
|
||||||
|
if (error)
|
||||||
|
error->clear();
|
||||||
|
|
||||||
|
QFile file {path};
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
if (error)
|
||||||
|
*error = file.errorString();
|
||||||
|
return TorrentInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
const qint64 fileSizeLimit = 100 * 1024 * 1024; // 100 MB
|
||||||
|
if (file.size() > fileSizeLimit) {
|
||||||
|
if (error)
|
||||||
|
*error = tr("File size exceeds max limit %1").arg(fileSizeLimit);
|
||||||
|
return TorrentInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray data = file.read(fileSizeLimit);
|
||||||
|
if (data.size() != file.size()) {
|
||||||
|
if (error)
|
||||||
|
*error = tr("Torrent file read error");
|
||||||
|
return TorrentInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// 2-step construction to overcome default limits of `depth_limit` & `token_limit` which are
|
||||||
|
// used in `torrent_info()` constructor
|
||||||
|
const int depthLimit = 100;
|
||||||
|
const int tokenLimit = 10000000;
|
||||||
|
libt::bdecode_node node;
|
||||||
libt::error_code ec;
|
libt::error_code ec;
|
||||||
TorrentInfo info(NativePtr(new libt::torrent_info(Utils::Fs::toNativePath(path).toStdString(), ec)));
|
bdecode(data.constData(), (data.constData() + data.size()), node, ec
|
||||||
if (error) {
|
, nullptr, depthLimit, tokenLimit);
|
||||||
if (ec)
|
if (ec) {
|
||||||
|
if (error)
|
||||||
*error = QString::fromStdString(ec.message());
|
*error = QString::fromStdString(ec.message());
|
||||||
else
|
return TorrentInfo();
|
||||||
error->clear();
|
}
|
||||||
|
|
||||||
|
TorrentInfo info {NativePtr(new libt::torrent_info(node, ec))};
|
||||||
|
if (ec) {
|
||||||
|
if (error)
|
||||||
|
*error = QString::fromStdString(ec.message());
|
||||||
|
return TorrentInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#ifndef BITTORRENT_TORRENTINFO_H
|
#ifndef BITTORRENT_TORRENTINFO_H
|
||||||
#define BITTORRENT_TORRENTINFO_H
|
#define BITTORRENT_TORRENTINFO_H
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include <libtorrent/torrent_info.hpp>
|
#include <libtorrent/torrent_info.hpp>
|
||||||
|
@ -51,6 +52,8 @@ namespace BitTorrent
|
||||||
|
|
||||||
class TorrentInfo
|
class TorrentInfo
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS("TorrentInfo")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if LIBTORRENT_VERSION_NUM < 10100
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
typedef boost::intrusive_ptr<const libtorrent::torrent_info> NativeConstPtr;
|
typedef boost::intrusive_ptr<const libtorrent::torrent_info> NativeConstPtr;
|
||||||
|
|
Loading…
Reference in a new issue