mirror of
https://github.com/transmission/transmission
synced 2024-12-23 08:13:27 +00:00
fix: some torrents think they are magnets (#5025)
This commit is contained in:
parent
81f8ceb0f9
commit
47fd150bab
2 changed files with 77 additions and 49 deletions
|
@ -1340,39 +1340,65 @@ namespace
|
|||
{
|
||||
namespace load_torrents_helpers
|
||||
{
|
||||
void session_load_torrents(tr_session* session, tr_ctor* ctor, std::promise<size_t>* loaded_promise)
|
||||
[[nodiscard]] std::vector<std::string> get_matching_files(
|
||||
std::string const& folder,
|
||||
std::function<bool(std::string_view)> const& test)
|
||||
{
|
||||
auto const& dirname = session->torrentDir();
|
||||
auto const info = tr_sys_path_get_info(dirname);
|
||||
auto const odir = info && info->isFolder() ? tr_sys_dir_open(dirname.c_str()) : TR_BAD_SYS_DIR;
|
||||
|
||||
auto n_torrents = size_t{};
|
||||
if (odir != TR_BAD_SYS_DIR)
|
||||
if (auto const info = tr_sys_path_get_info(folder); !info || !info->isFolder())
|
||||
{
|
||||
char const* name = nullptr;
|
||||
while ((name = tr_sys_dir_read_name(odir)) != nullptr)
|
||||
return {};
|
||||
}
|
||||
|
||||
auto const odir = tr_sys_dir_open(folder.c_str());
|
||||
if (odir == TR_BAD_SYS_DIR)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto filenames = std::vector<std::string>{};
|
||||
for (;;)
|
||||
{
|
||||
char const* const name = tr_sys_dir_read_name(odir);
|
||||
|
||||
if (name == nullptr)
|
||||
{
|
||||
if (!tr_strvEndsWith(name, ".torrent"sv) && !tr_strvEndsWith(name, ".magnet"sv))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// is a magnet link?
|
||||
if (auto const path = tr_pathbuf{ dirname, '/', name }; !tr_ctorSetMetainfoFromFile(ctor, path.sv(), nullptr))
|
||||
{
|
||||
if (auto buf = std::vector<char>{}; tr_loadFile(path, buf))
|
||||
{
|
||||
tr_ctorSetMetainfoFromMagnetLink(ctor, std::string_view{ std::data(buf), std::size(buf) }, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr_torrentNew(ctor, nullptr) != nullptr)
|
||||
{
|
||||
++n_torrents;
|
||||
}
|
||||
tr_sys_dir_close(odir);
|
||||
return filenames;
|
||||
}
|
||||
|
||||
tr_sys_dir_close(odir);
|
||||
if (test(name))
|
||||
{
|
||||
filenames.emplace_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void session_load_torrents(tr_session* session, tr_ctor* ctor, std::promise<size_t>* loaded_promise)
|
||||
{
|
||||
auto n_torrents = size_t{};
|
||||
auto const& folder = session->torrentDir();
|
||||
|
||||
for (auto const& name : get_matching_files(folder, [](auto const& name) { return tr_strvEndsWith(name, ".torrent"sv); }))
|
||||
{
|
||||
auto const path = tr_pathbuf{ folder, '/', name };
|
||||
|
||||
if (tr_ctorSetMetainfoFromFile(ctor, path.sv(), nullptr) && tr_torrentNew(ctor, nullptr) != nullptr)
|
||||
{
|
||||
++n_torrents;
|
||||
}
|
||||
}
|
||||
|
||||
auto buf = std::vector<char>{};
|
||||
for (auto const& name : get_matching_files(folder, [](auto const& name) { return tr_strvEndsWith(name, ".magnet"sv); }))
|
||||
{
|
||||
auto const path = tr_pathbuf{ folder, '/', name };
|
||||
|
||||
if (tr_loadFile(path, buf) &&
|
||||
tr_ctorSetMetainfoFromMagnetLink(ctor, std::string_view{ std::data(buf), std::size(buf) }, nullptr) &&
|
||||
tr_torrentNew(ctor, nullptr) != nullptr)
|
||||
{
|
||||
++n_torrents;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_torrents != 0U)
|
||||
|
|
|
@ -510,12 +510,6 @@ private:
|
|||
|
||||
bool finish(Context const& context)
|
||||
{
|
||||
// Support Transmission <= 3.0 magnets stored in torrent format.
|
||||
if (tm_.has_magnet_info_hash_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// bittorrent 1.0 spec
|
||||
// http://bittorrent.org/beps/bep_0003.html
|
||||
//
|
||||
|
@ -529,26 +523,34 @@ private:
|
|||
tm_.files_.add(tm_.name_, length_);
|
||||
}
|
||||
|
||||
if (tm_.fileCount() == 0)
|
||||
if (auto const has_metainfo = tm_.infoDictSize() != 0U; has_metainfo)
|
||||
{
|
||||
if (!tr_error_is_set(context.error))
|
||||
// do some sanity checks to make sure the torrent looks sane
|
||||
if (tm_.fileCount() == 0)
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, "no files found");
|
||||
if (!tr_error_is_set(context.error))
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, "no files found");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (piece_size_ == 0)
|
||||
{
|
||||
if (!tr_error_is_set(context.error))
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, fmt::format("invalid piece size: {}", piece_size_));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
tm_.block_info_.initSizes(tm_.files_.totalSize(), piece_size_);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (piece_size_ == 0)
|
||||
{
|
||||
if (!tr_error_is_set(context.error))
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, fmt::format("invalid piece size: {}", piece_size_));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
tm_.block_info_.initSizes(tm_.files_.totalSize(), piece_size_);
|
||||
return true;
|
||||
// no metainfo; might be a Transmission 3.00-style magnet file
|
||||
auto const ok = tm_.has_magnet_info_hash_;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static constexpr std::string_view AcodecKey = "acodec"sv;
|
||||
|
|
Loading…
Reference in a new issue