Merge pull request #12317 from sledgehammer999/fix_broken_save_path

Fix broken UNC paths in fastresumes on Windows
This commit is contained in:
sledgehammer999 2020-03-31 18:34:31 +03:00 committed by GitHub
commit bbe5465ba6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -53,6 +53,12 @@
#include <QTimer> #include <QTimer>
#include <QUuid> #include <QUuid>
#ifdef Q_OS_WIN
// TODO: Remove together with fixBrokenSavePath()
#define NEED_TO_FIX_BROKEN_PATH
#include <QSaveFile>
#endif
#include <libtorrent/alert_types.hpp> #include <libtorrent/alert_types.hpp>
#include <libtorrent/bdecode.hpp> #include <libtorrent/bdecode.hpp>
#include <libtorrent/bencode.hpp> #include <libtorrent/bencode.hpp>
@ -141,17 +147,72 @@ namespace
return true; return true;
} }
#ifdef NEED_TO_FIX_BROKEN_PATH
// TODO: Remove this after 4.2.5 && if at least one month has passed from v4.2.3
// Check the commit that introduced this function and identify all other pieces of code that
// need removal alongside this one.
void fixBrokenSavePath(QByteArray &data, lt::bdecode_node &root)
{
const QString path = fromLTString(root.dict_find_string_value("save_path"));
const int index = path.indexOf(QLatin1String("//"));
if (index < 1)
return;
const QString goodPath = path.mid(index).replace('/', '\\');
lt::entry entry {root};
entry["save_path"] = goodPath.toStdString();
const auto rawView = root.dict_find_string_value("info-hash");
const QByteArray rawHashView = QByteArray::fromRawData(rawView.data(), rawView.length());
const QString hexHash = QString::fromLatin1(rawHashView.toHex());
data.clear();
lt::bencode(std::back_inserter(data), entry);
const QString filename = QString("%1.fastresume").arg(hexHash);
const QDir resumeDataDir {Utils::Fs::expandPathAbs(specialFolderLocation(SpecialFolder::Data) + RESUME_FOLDER)};
const QString filepath = resumeDataDir.absoluteFilePath(filename);
QSaveFile file {filepath};
if (file.open(QIODevice::WriteOnly)) {
file.write(data);
if (!file.commit()) {
Logger::instance()->addMessage(QString("Couldn't save data in '%1'. Error: %2")
.arg(filepath, file.errorString()), Log::WARNING);
}
}
lt::error_code ec;
#if (LIBTORRENT_VERSION_NUM < 10200)
lt::bdecode(data.constData(), (data.constData() + data.size()), root, ec);
#else
root = lt::bdecode(data, ec);
#endif
}
#endif
#ifdef NEED_TO_FIX_BROKEN_PATH
// TODO: Remove together with fixBrokenSavePath()
bool loadTorrentResumeData(QByteArray &data, CreateTorrentParams &torrentParams, int &queuePos, MagnetUri &magnetUri)
#else
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &queuePos, MagnetUri &magnetUri) bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &queuePos, MagnetUri &magnetUri)
#endif
{ {
lt::error_code ec; lt::error_code ec;
#if (LIBTORRENT_VERSION_NUM < 10200) #if (LIBTORRENT_VERSION_NUM < 10200)
lt::bdecode_node root; lt::bdecode_node root;
lt::bdecode(data.constData(), (data.constData() + data.size()), root, ec); lt::bdecode(data.constData(), (data.constData() + data.size()), root, ec);
#elif defined(NEED_TO_FIX_BROKEN_PATH)
// TODO: Remove together with fixBrokenSavePath()
lt::bdecode_node root = lt::bdecode(data, ec);
#else #else
const lt::bdecode_node root = lt::bdecode(data, ec); const lt::bdecode_node root = lt::bdecode(data, ec);
#endif #endif
if (ec || (root.type() != lt::bdecode_node::dict_t)) return false; if (ec || (root.type() != lt::bdecode_node::dict_t)) return false;
#ifdef NEED_TO_FIX_BROKEN_PATH
fixBrokenSavePath(data, root);
#endif
torrentParams = CreateTorrentParams(); torrentParams = CreateTorrentParams();
torrentParams.restored = true; torrentParams.restored = true;