Don't stuck loading on mismatching info-hashes in resume data

PR #20262.
Closes #20251.
This commit is contained in:
Vladimir Golovnev 2024-01-13 20:35:46 +03:00 committed by GitHub
parent c894d84ed3
commit 17b6dcfbef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 13 deletions

View file

@ -288,6 +288,16 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre
return nonstd::make_unexpected(tr("Cannot parse torrent info: %1").arg(QString::fromStdString(ec.message())));
p.ti = torrentInfo;
#ifdef QBT_USES_LIBTORRENT2
if (((p.info_hashes.has_v1() && (p.info_hashes.v1 != p.ti->info_hashes().v1))
|| (p.info_hashes.has_v2() && (p.info_hashes.v2 != p.ti->info_hashes().v2))))
#else
if (!p.info_hash.is_all_zeros() && (p.info_hash != p.ti->info_hash()))
#endif
{
return nonstd::make_unexpected(tr("Mismatching info-hash detected in resume data"));
}
}
p.save_path = Profile::instance()->fromPortablePath(

View file

@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
@ -1217,13 +1217,13 @@ void SessionImpl::prepareStartup()
context->isLoadFinished = true;
});
connect(this, &SessionImpl::torrentsLoaded, context, [this, context](const QVector<Torrent *> &torrents)
connect(this, &SessionImpl::addTorrentAlertsReceived, context, [this, context](const qsizetype alertsCount)
{
context->processingResumeDataCount -= torrents.count();
context->finishedResumeDataCount += torrents.count();
context->processingResumeDataCount -= alertsCount;
context->finishedResumeDataCount += alertsCount;
if (!context->isLoadedResumeDataHandlingEnqueued)
{
QMetaObject::invokeMethod(this, [this, context]() { handleLoadedResumeData(context); }, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, [this, context] { handleLoadedResumeData(context); }, Qt::QueuedConnection);
context->isLoadedResumeDataHandlingEnqueued = true;
}
@ -5460,11 +5460,14 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
if (!isRestored())
loadedTorrents.reserve(MAX_PROCESSING_RESUMEDATA_COUNT);
qsizetype alertsCount = 0;
for (const lt::alert *a : alerts)
{
if (a->type() != lt::add_torrent_alert::alert_type)
continue;
++alertsCount;
const auto *alert = static_cast<const lt::add_torrent_alert *>(a);
if (alert->error)
{
@ -5474,6 +5477,7 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
const lt::add_torrent_params &params = alert->params;
const bool hasMetadata = (params.ti && params.ti->is_valid());
#ifdef QBT_USES_LIBTORRENT2
const InfoHash infoHash {(hasMetadata ? params.ti->info_hashes() : params.info_hashes)};
if (infoHash.isHybrid())
@ -5498,10 +5502,9 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
}
}
return;
continue;
}
#ifdef QBT_USES_LIBTORRENT2
const InfoHash infoHash {alert->handle.info_hashes()};
#else
@ -5531,6 +5534,10 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
}
}
if (alertsCount > 0)
{
emit addTorrentAlertsReceived(alertsCount);
if (!loadedTorrents.isEmpty())
{
if (isRestored())
@ -5538,6 +5545,7 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
emit torrentsLoaded(loadedTorrents);
}
}
}
void SessionImpl::handleAlert(const lt::alert *a)
{

View file

@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
@ -475,6 +475,9 @@ namespace BitTorrent
void invokeAsync(std::function<void ()> func);
signals:
void addTorrentAlertsReceived(qsizetype count);
private slots:
void configureDeferred();
void readAlerts();