diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 21b85ea31..0ce5a23bd 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -82,6 +82,7 @@ #include "base/torrentfileguard.h" #include "base/torrentfilter.h" #include "base/unicodestrings.h" +#include "base/utils/bytearray.h" #include "base/utils/fs.h" #include "base/utils/misc.h" #include "base/utils/net.h" @@ -2088,6 +2089,23 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne patchedFastresumeData.replace("6:pausedi0e", "6:pausedi1e"); patchedFastresumeData.replace("12:auto_managedi0e", "12:auto_managedi1e"); + // converting relative save_path to absolute + int start = patchedFastresumeData.indexOf("9:save_path"); + if (start > -1) { + start += 11; + const int end = patchedFastresumeData.indexOf(':', start); + const int len = Utils::ByteArray::midView(patchedFastresumeData, start, (end - start)).toInt(); + if (len > 0) { + const QByteArray relativePath = Utils::ByteArray::midView(patchedFastresumeData, (end + 1), len); + const QByteArray absolutePath = Profile::instance()->fromPortablePath(Utils::Fs::toUniformPath(QString::fromUtf8(relativePath))).toUtf8(); + if (relativePath != absolutePath) { + const QByteArray replaceBefore = "9:save_path" + QByteArray::number(len) + ':' + relativePath; + const QByteArray replaceAfter = "9:save_path" + QByteArray::number(absolutePath.size()) + ':' + absolutePath; + patchedFastresumeData.replace(replaceBefore, replaceAfter); + } + } + } + p.resume_data = std::vector {patchedFastresumeData.constData() , (patchedFastresumeData.constData() + patchedFastresumeData.size())}; p.flags |= lt::add_torrent_params::flag_use_resume_save_path; @@ -2251,6 +2269,7 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne if (params.restored) { // load from existing fastresume lt::error_code ec; p = lt::read_resume_data(fastresumeData, ec); + p.save_path = Profile::instance()->fromPortablePath(Utils::Fs::toUniformPath(fromLTString(p.save_path))).toStdString(); } else { // new torrent if (!params.hasRootFolder) diff --git a/src/base/private/profile_p.cpp b/src/base/private/profile_p.cpp index db8bc19d3..e930dac4d 100644 --- a/src/base/private/profile_p.cpp +++ b/src/base/private/profile_p.cpp @@ -179,7 +179,7 @@ QString Private::Converter::toPortablePath(const QString &path) const QString Private::Converter::fromPortablePath(const QString &portablePath) const { - if (QDir::isAbsolutePath(portablePath)) + if (portablePath.isEmpty() || QDir::isAbsolutePath(portablePath)) return portablePath; return QDir::cleanPath(m_baseDir.absoluteFilePath(portablePath)); diff --git a/src/base/profile.cpp b/src/base/profile.cpp index 44408d295..24d168e42 100644 --- a/src/base/profile.cpp +++ b/src/base/profile.cpp @@ -33,13 +33,21 @@ Profile *Profile::m_instance = nullptr; -Profile::Profile(Private::Profile *impl, Private::PathConverter *pathConverter) - : m_profileImpl(impl) - , m_pathConverterImpl(pathConverter) +Profile::Profile(const QString &rootProfilePath, const QString &configurationName, const bool convertPathsToProfileRelative) { + if (rootProfilePath.isEmpty()) + m_profileImpl = std::make_unique(configurationName); + else + m_profileImpl = std::make_unique(rootProfilePath, configurationName); + ensureDirectoryExists(SpecialFolder::Cache); ensureDirectoryExists(SpecialFolder::Config); ensureDirectoryExists(SpecialFolder::Data); + + if (convertPathsToProfileRelative) + m_pathConverterImpl = std::make_unique(m_profileImpl->baseDirectory()); + else + m_pathConverterImpl = std::make_unique(); } void Profile::initInstance(const QString &rootProfilePath, const QString &configurationName, @@ -47,14 +55,7 @@ void Profile::initInstance(const QString &rootProfilePath, const QString &config { if (m_instance) return; - - std::unique_ptr profile(rootProfilePath.isEmpty() - ? static_cast(new Private::DefaultProfile(configurationName)) - : static_cast(new Private::CustomProfile(rootProfilePath, configurationName))); - std::unique_ptr converter(convertPathsToProfileRelative - ? static_cast(new Private::Converter(profile->baseDirectory())) - : static_cast(new Private::NoConvertConverter())); - m_instance = new Profile(profile.release(), converter.release()); + m_instance = new Profile(rootProfilePath, configurationName, convertPathsToProfileRelative); } void Profile::freeInstance() diff --git a/src/base/profile.h b/src/base/profile.h index 6568f3eef..c2445f158 100644 --- a/src/base/profile.h +++ b/src/base/profile.h @@ -71,13 +71,13 @@ public: QString fromPortablePath(const QString &portablePath) const; private: - Profile(Private::Profile *impl, Private::PathConverter *pathConverter); + Profile(const QString &rootProfilePath, const QString &configurationName, bool convertPathsToProfileRelative); ~Profile() = default; // to generate correct call to ProfilePrivate::~ProfileImpl() void ensureDirectoryExists(SpecialFolder folder) const; - const std::unique_ptr m_profileImpl; - const std::unique_ptr m_pathConverterImpl; + std::unique_ptr m_profileImpl; + std::unique_ptr m_pathConverterImpl; static Profile *m_instance; };