Prevent loading resume data with inconsistent ID

This commit is contained in:
Vladimir Golovnev (Glassez) 2022-03-02 14:16:33 +03:00
parent 299f981441
commit cbc0ef860b
No known key found for this signature in database
GPG key ID: 52A2C7DEE2DFA6F7

View file

@ -4480,53 +4480,62 @@ void Session::startUpTorrents()
const lt::info_hash_t infoHash = (resumeData.ltAddTorrentParams.ti const lt::info_hash_t infoHash = (resumeData.ltAddTorrentParams.ti
? resumeData.ltAddTorrentParams.ti->info_hashes() ? resumeData.ltAddTorrentParams.ti->info_hashes()
: resumeData.ltAddTorrentParams.info_hashes); : resumeData.ltAddTorrentParams.info_hashes);
if (infoHash.has_v1() && infoHash.has_v2()) const bool isHybrid = infoHash.has_v1() && infoHash.has_v2();
const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash);
const auto torrentIDv1 = TorrentID::fromInfoHash(lt::info_hash_t(infoHash.v1));
if (torrentID == torrentIDv2)
{ {
const auto torrentIDv1 = TorrentID::fromInfoHash(lt::info_hash_t(infoHash.v1)); if (isHybrid && indexedTorrents.contains(torrentIDv1))
const auto torrentIDv2 = TorrentID::fromInfoHash(infoHash);
if (torrentID == torrentIDv2)
{ {
if (indexedTorrents.contains(torrentIDv1)) // if we don't have metadata, try to find it in alternative "resume data"
if (!resumeData.ltAddTorrentParams.ti)
{ {
// if we has no metadata trying to find it in alternative "resume data" const std::optional<LoadTorrentParams> loadAltResumeDataResult = startupStorage->load(torrentIDv1);
if (!resumeData.ltAddTorrentParams.ti) if (loadAltResumeDataResult)
{ resumeData.ltAddTorrentParams.ti = loadAltResumeDataResult->ltAddTorrentParams.ti;
const std::optional<LoadTorrentParams> loadAltResumeDataResult = startupStorage->load(torrentIDv1);
if (loadAltResumeDataResult)
{
LoadTorrentParams altResumeData = *loadAltResumeDataResult;
resumeData.ltAddTorrentParams.ti = altResumeData.ltAddTorrentParams.ti;
}
}
// remove alternative "resume data" and skip the attempt to load it
m_resumeDataStorage->remove(torrentIDv1);
skippedIDs.insert(torrentIDv1);
} }
}
else // remove alternative "resume data" and skip the attempt to load it
{
torrentID = torrentIDv2;
needStore = true;
m_resumeDataStorage->remove(torrentIDv1); m_resumeDataStorage->remove(torrentIDv1);
skippedIDs.insert(torrentIDv1);
}
}
else if (torrentID == torrentIDv1)
{
torrentID = torrentIDv2;
needStore = true;
m_resumeDataStorage->remove(torrentIDv1);
if (indexedTorrents.contains(torrentID)) if (indexedTorrents.contains(torrentID))
{
skippedIDs.insert(torrentID);
const std::optional<LoadTorrentParams> loadPreferredResumeDataResult = startupStorage->load(torrentID);
if (loadPreferredResumeDataResult)
{ {
skippedIDs.insert(torrentID); std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti;
resumeData = *loadPreferredResumeDataResult;
const std::optional<LoadTorrentParams> loadPreferredResumeDataResult = startupStorage->load(torrentID); if (!resumeData.ltAddTorrentParams.ti)
if (loadPreferredResumeDataResult) resumeData.ltAddTorrentParams.ti = ti;
{
LoadTorrentParams preferredResumeData = *loadPreferredResumeDataResult;
std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti;
if (!preferredResumeData.ltAddTorrentParams.ti)
preferredResumeData.ltAddTorrentParams.ti = ti;
resumeData = preferredResumeData;
}
} }
} }
} }
else
{
LogMsg(tr("Failed to resume torrent: inconsistent torrent ID is detected. Torrent: \"%1\"")
.arg(torrentID.toString()), Log::WARNING);
continue;
}
#else
const lt::sha1_hash infoHash = (resumeData.ltAddTorrentParams.ti
? resumeData.ltAddTorrentParams.ti->info_hash()
: resumeData.ltAddTorrentParams.info_hash);
if (torrentID != TorrentID::fromInfoHash(infoHash))
{
LogMsg(tr("Failed to resume torrent: inconsistent torrent ID is detected. Torrent: \"%1\"")
.arg(torrentID.toString()), Log::WARNING);
continue;
}
#endif #endif
if (m_resumeDataStorage != startupStorage) if (m_resumeDataStorage != startupStorage)