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()))); return nonstd::make_unexpected(tr("Cannot parse torrent info: %1").arg(QString::fromStdString(ec.message())));
p.ti = torrentInfo; 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( p.save_path = Profile::instance()->fromPortablePath(

View file

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

View file

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