From 16acd9ebe1932b802144f4637a26601daa111ab4 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 13 May 2019 22:46:17 -0700 Subject: [PATCH] don't leak exceptions out of handler callbacks in resolver --- include/libtorrent/resolver.hpp | 5 ++++- src/resolver.cpp | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/libtorrent/resolver.hpp b/include/libtorrent/resolver.hpp index 24eaa00bc..75bb6fc55 100644 --- a/include/libtorrent/resolver.hpp +++ b/include/libtorrent/resolver.hpp @@ -62,7 +62,10 @@ struct TORRENT_EXTRA_EXPORT resolver final : resolver_interface private: void on_lookup(error_code const& ec, tcp::resolver::iterator i - , resolver_interface::callback_t h, std::string hostname); + , resolver_interface::callback_t const& h, std::string const& hostname); + + void callback(resolver_interface::callback_t const& h + , error_code const& ec, std::vector
const& ips); struct dns_cache_entry { diff --git a/src/resolver.cpp b/src/resolver.cpp index c6281b4c2..a3f68dccc 100644 --- a/src/resolver.cpp +++ b/src/resolver.cpp @@ -48,13 +48,24 @@ namespace libtorrent { , m_timeout(seconds(1200)) {} + + void resolver::callback(resolver_interface::callback_t const& h + , error_code const& ec, std::vector
const& ips) + { + try { + h(ec, ips); + } catch (std::exception&) { + TORRENT_ASSERT_FAIL(); + } + } + void resolver::on_lookup(error_code const& ec, tcp::resolver::iterator i - , resolver_interface::callback_t h, std::string hostname) + , resolver_interface::callback_t const& h, std::string const& hostname) { COMPLETE_ASYNC("resolver::on_lookup"); if (ec) { - h(ec, {}); + callback(h, ec, {}); return; } @@ -67,7 +78,7 @@ namespace libtorrent { ++i; } - h(ec, ce.addresses); + callback(h, ec, ce.addresses); // if m_cache grows too big, weed out the // oldest entries @@ -94,7 +105,7 @@ namespace libtorrent { address const ip = make_address(host, ec); if (!ec) { - m_ios.post(std::bind(h, ec, std::vector
{ip})); + m_ios.post([=]{ callback(h, ec, std::vector
{ip}); }); return; } ec.clear(); @@ -106,7 +117,8 @@ namespace libtorrent { if ((flags & resolver_interface::cache_only) || i->second.last_seen + m_timeout >= aux::time_now()) { - m_ios.post(std::bind(h, ec, i->second.addresses)); + std::vector
ips = i->second.addresses; + m_ios.post([=] { callback(h, ec, ips); }); return; } } @@ -114,8 +126,9 @@ namespace libtorrent { if (flags & resolver_interface::cache_only) { // we did not find a cache entry, fail the lookup - m_ios.post(std::bind(h, boost::asio::error::host_not_found - , std::vector
{})); + m_ios.post([=] { + callback(h, boost::asio::error::host_not_found, std::vector
{}); + }); return; }