diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 159cafd9..4170b2bf 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -128,27 +128,33 @@ DownloadFactory::load_untrusted(const std::string& uri) { } void -DownloadFactory::load_raw_data(const std::string& input) { +DownloadFactory::load_raw_data_trusted(const std::string& input) { + if (!m_trusted) + throw torrent::internal_error("DownloadFactory::load_raw_data_trusted() called on an untrusted object"); + if (m_stream) - throw torrent::internal_error("DownloadFactory::load_raw_data() called on an object with m_stream != NULL"); + throw torrent::internal_error("DownloadFactory::load_raw_data_trusted() called on an object with m_stream != NULL"); m_stream.reset(new std::stringstream(input)); m_loaded = true; } void -DownloadFactory::commit_trusted() { - if (!m_trusted) - throw torrent::internal_error("DownloadFactory::commit_trusted() called on an untrusted object"); +DownloadFactory::load_raw_data_untrusted(const std::string& input) { + if (m_trusted) + throw torrent::internal_error("DownloadFactory::load_raw_data_untrusted() called on an trusted object"); - m_task_commit.slot() = [this]() { receive_commit(); }; - torrent::this_thread::scheduler()->wait_for(&m_task_commit, 0ms); + if (m_stream) + throw torrent::internal_error("DownloadFactory::load_raw_data_untrusted() called on an object with m_stream != NULL"); + + m_stream.reset(new std::stringstream(input)); + m_loaded = true; } void -DownloadFactory::commit_untrusted() { - if (m_trusted) - throw torrent::internal_error("DownloadFactory::commit_untrusted() called on a trusted object"); +DownloadFactory::commit() { + if (!m_trusted) + throw torrent::internal_error("DownloadFactory::commit() called on an untrusted object"); m_task_commit.slot() = [this]() { receive_commit(); }; torrent::this_thread::scheduler()->wait_for(&m_task_commit, 0ms); diff --git a/src/core/download_factory.h b/src/core/download_factory.h index 31b5b3e1..3c7ab9c6 100644 --- a/src/core/download_factory.h +++ b/src/core/download_factory.h @@ -33,10 +33,10 @@ public: void load_trusted(const std::string& uri); void load_untrusted(const std::string& uri); - void load_raw_data(const std::string& input); + void load_raw_data_trusted(const std::string& input); + void load_raw_data_untrusted(const std::string& input); - void commit_trusted(); - void commit_untrusted(); + void commit(); command_list_type& commands() { return m_commands; } torrent::Object::map_type& variables() { return m_variables; } diff --git a/src/core/manager.cc b/src/core/manager.cc index 607e898d..a5eadc15 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -197,7 +197,7 @@ Manager::try_create_download(const std::string& uri, int flags, const command_li return; // Adding download. - DownloadFactory* f = new DownloadFactory(this); + DownloadFactory* f = new DownloadFactory(this, true); f->variables()["tied_to_file"] = (int64_t)(bool)(flags & create_tied); f->commands().insert(f->commands().end(), commands.begin(), commands.end()); @@ -207,16 +207,16 @@ Manager::try_create_download(const std::string& uri, int flags, const command_li f->slot_finished([f]() { delete f; }); if (flags & create_raw_data) { - f->load_raw_data(uri); + f->load_raw_data_trusted(uri); } else if (is_data_uri(uri)) { // Allow the use of data URIs, primarily for JSON-RPC which // doesn't have a defined mechanism for binary data - f->load_raw_data(decode_data_uri(uri)); + f->load_raw_data_trusted(decode_data_uri(uri)); f->variables()["tied_to_file"] = (int64_t)false; } else { - f->load(uri); + f->load_trusted(uri); } f->commit(); @@ -244,13 +244,14 @@ Manager::try_create_download_expand(const std::string& uri, int flags, command_l void Manager::try_create_download_from_meta_download(torrent::Object* bencode, const std::string& metafile) { - DownloadFactory* f = new DownloadFactory(this); + DownloadFactory* f = new DownloadFactory(this, true); f->variables()["tied_to_file"] = (int64_t)true; - f->variables()["tied_file"] = metafile; + f->variables()["tied_file"] = metafile; torrent::Object& meta = bencode->get_key("rtorrent_meta_download"); torrent::Object::list_type& commands = meta.get_key_list("commands"); + for (const auto& command : commands) f->commands().insert(f->commands().end(), command.as_string()); @@ -263,7 +264,8 @@ Manager::try_create_download_from_meta_download(torrent::Object* bencode, const std::stringstream s; s.imbue(std::locale::classic()); s << *bencode; - f->load_raw_data(s.str()); + + f->load_raw_data_trusted(s.str()); f->commit(); } @@ -279,8 +281,7 @@ Manager::try_create_download_untrusted(const std::string& uri, int flags, const return; } - // Adding download. - DownloadFactory* f = new DownloadFactory(this); + DownloadFactory* f = new DownloadFactory(this, false); f->commands().insert(f->commands().end(), commands.begin(), commands.end()); @@ -299,10 +300,10 @@ Manager::try_create_download_untrusted(const std::string& uri, int flags, const } else { // f->load_untrusted(uri); - throw internal_error("Manager::try_create_download_untrusted() unimplemented."); + throw torrent::internal_error("Manager::try_create_download_untrusted() unimplemented."); } - f->commit_untrusted(); + f->commit(); } namespace { diff --git a/src/setup.cc b/src/setup.cc index 9aefaec6..baeec744 100644 --- a/src/setup.cc +++ b/src/setup.cc @@ -157,12 +157,12 @@ load_session_torrents(const std::string& path) { if (!entry.is_file()) continue; - auto* f = new core::DownloadFactory(control->core()); + auto* f = new core::DownloadFactory(control->core(), true); f->set_session(true); f->set_init_load(true); f->slot_finished([f](){ delete f; }); - f->load(entries.path() + entry.s_name); + f->load_trusted(entries.path() + entry.s_name); f->commit(); } } @@ -170,12 +170,12 @@ load_session_torrents(const std::string& path) { void load_arg_torrents(char** first, char** last) { for (; first != last; ++first) { - auto* f = new core::DownloadFactory(control->core()); + auto* f = new core::DownloadFactory(control->core(), true); f->set_start(true); f->set_init_load(true); f->slot_finished([f](){ delete f; }); - f->load(*first); + f->load_trusted(*first); f->commit(); } }