From 3eac1700a1b5a8403b9353477d47b1d1535440d8 Mon Sep 17 00:00:00 2001
From: Chocobo1 <Chocobo1@users.noreply.github.com>
Date: Mon, 20 May 2019 11:43:52 +0800
Subject: [PATCH 1/7] Don't leak exceptions out of handler callbacks in
 resolver

---
 include/libtorrent/resolver.hpp |  5 ++++-
 src/resolver.cpp                | 23 +++++++++++++++++------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/libtorrent/resolver.hpp b/include/libtorrent/resolver.hpp
index f713da9aae..b61d2d2a3e 100644
--- a/include/libtorrent/resolver.hpp
+++ b/include/libtorrent/resolver.hpp
@@ -64,7 +64,10 @@ struct TORRENT_EXTRA_EXPORT resolver TORRENT_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<address> const& ips);
 
 	struct dns_cache_entry
 	{
diff --git a/src/resolver.cpp b/src/resolver.cpp
index 20753c15de..2708e31f83 100644
--- a/src/resolver.cpp
+++ b/src/resolver.cpp
@@ -45,8 +45,18 @@ namespace libtorrent
 		, m_timeout(seconds(1200))
 	{}
 
+	void resolver::callback(resolver_interface::callback_t const& h
+		, error_code const& ec, std::vector<address> const& ips)
+	{
+		try {
+			h(ec, ips);
+		} catch (std::exception&) {
+			TORRENT_ASSERT(false);
+		}
+	}
+
 	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)
 	{
 #if defined TORRENT_ASIO_DEBUGGING
 		complete_async("resolver::on_lookup");
@@ -54,7 +64,7 @@ namespace libtorrent
 		if (ec)
 		{
 			std::vector<address> empty;
-			h(ec, empty);
+			callback(h, ec, empty);
 			return;
 		}
 
@@ -68,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
@@ -98,7 +108,7 @@ namespace libtorrent
 		{
 			std::vector<address> addresses;
 			addresses.push_back(ip);
-			m_ios.post(boost::bind(h, ec, addresses));
+			m_ios.post(boost::bind(&resolver::callback, this, h, ec, addresses));
 			return;
 		}
 		ec.clear();
@@ -110,7 +120,8 @@ namespace libtorrent
 			if ((flags & resolver_interface::cache_only)
 				|| i->second.last_seen + m_timeout >= aux::time_now())
 			{
-				m_ios.post(boost::bind(h, ec, i->second.addresses));
+				std::vector<address> ips = i->second.addresses;
+				m_ios.post(boost::bind(&resolver::callback, this, h, ec, ips));
 				return;
 			}
 		}
@@ -118,7 +129,7 @@ namespace libtorrent
 		if (flags & resolver_interface::cache_only)
 		{
 			// we did not find a cache entry, fail the lookup
-			m_ios.post(boost::bind(h, boost::asio::error::host_not_found
+			m_ios.post(boost::bind(&resolver::callback, this, h, boost::asio::error::host_not_found
 					, std::vector<address>()));
 			return;
 		}

From bfff982ba8e36633ef6f161e57046ed8f6385a94 Mon Sep 17 00:00:00 2001
From: Arvid Norberg <arvid@cs.umu.se>
Date: Sat, 29 Jun 2019 16:17:26 +0200
Subject: [PATCH 2/7] fix bug in python binding parsing file_priorities from
 add_torrent_params

---
 bindings/python/src/session.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp
index 283b531556..d89988a2f6 100644
--- a/bindings/python/src/session.cpp
+++ b/bindings/python/src/session.cpp
@@ -322,9 +322,9 @@ namespace
         {
             list l = extract<list>(params["file_priorities"]);
             int n = boost::python::len(l);
+            p.file_priorities.clear();
             for(int i = 0; i < n; i++)
                 p.file_priorities.push_back(extract<boost::uint8_t>(l[i]));
-            p.file_priorities.clear();
         }
     }
 

From 694e08a01241ee79848a4e8af7876f9958b62de8 Mon Sep 17 00:00:00 2001
From: patch3proxyheaders915360
 <patch3proxyheaders915360@users.noreply.github.com>
Date: Thu, 27 Jun 2019 10:02:55 +0000
Subject: [PATCH 3/7] set HTTP Host to request-target when using proxy

To make the Host field carry the request-target it is enough to set
the Host information before changing the connection destination.

Many proxies rely on the Host field-value to route requests
in a violation of RFC7230 section 5.4.

https://tools.ietf.org/html/rfc7230#section-5.4

A request with the Host field set to the proxy hostname and port
in place of the request-target produces error responses and otherwise
confuses such misconfigured middleboxes.
---
 src/http_connection.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/http_connection.cpp b/src/http_connection.cpp
index 15f6ef9ac5..21e7ccfb65 100644
--- a/src/http_connection.cpp
+++ b/src/http_connection.cpp
@@ -187,12 +187,12 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
 			request << "Proxy-Authorization: Basic " << base64encode(
 				ps->username + ":" + ps->password) << "\r\n";
 
-		hostname = ps->hostname;
-		port = ps->port;
-
 		request << "Host: " << hostname;
 		if (port != default_port) request << ":" << port << "\r\n";
 		else request << "\r\n";
+
+		hostname = ps->hostname;
+		port = ps->port;
 	}
 	else
 	{

From 13b07ef998ffdade9bab447d6640446d8fe8268f Mon Sep 17 00:00:00 2001
From: Arvid Norberg <arvid@cs.umu.se>
Date: Sun, 30 Jun 2019 11:34:40 +0200
Subject: [PATCH 4/7] fix error handling of moving storage to a drive letter
 that isn't mounted

---
 src/file.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/file.cpp b/src/file.cpp
index a792f6a6ea..ad1f198a32 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -501,7 +501,14 @@ namespace libtorrent
 		if (ec != boost::system::errc::no_such_file_or_directory)
 			return;
 		ec.clear();
-		if (is_root_path(f)) return;
+		if (is_root_path(f))
+		{
+			// this is just to set ec correctly, in case this root path isn't
+			// mounted
+			file_status s;
+			stat_file(f, &s, ec);
+			return;
+		}
 		if (has_parent_path(f))
 		{
 			create_directories(parent_path(f), ec);

From b6274481989f97c65d0f5609f318d7787999cb1e Mon Sep 17 00:00:00 2001
From: arvidn <arvid@libtorrent.org>
Date: Sat, 20 Jul 2019 10:44:25 -0700
Subject: [PATCH 5/7] make sure to destruct the existing value in entry when
 assigning from bdecode_node and lazy_entry

---
 src/entry.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/entry.cpp b/src/entry.cpp
index 2e0991515c..d3506cd5f0 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -357,6 +357,7 @@ namespace libtorrent
 	// convert a bdecode_node into an old skool entry
 	void entry::operator=(bdecode_node const& e)
 	{
+		destruct();
 		switch (e.type())
 		{
 			case bdecode_node::string_t:
@@ -386,7 +387,6 @@ namespace libtorrent
 				break;
 			}
 			case bdecode_node::none_t:
-				destruct();
 				break;
 		}
 	}
@@ -395,6 +395,7 @@ namespace libtorrent
 	// convert a lazy_entry into an old skool entry
 	void entry::operator=(lazy_entry const& e)
 	{
+		destruct();
 		switch (e.type())
 		{
 			case lazy_entry::string_t:
@@ -424,7 +425,6 @@ namespace libtorrent
 				break;
 			}
 			case lazy_entry::none_t:
-				destruct();
 				break;
 		}
 	}

From d9fd5ad27f58b5caf2597d2a944805f4a4cc3c31 Mon Sep 17 00:00:00 2001
From: arvidn <arvid@libtorrent.org>
Date: Sat, 20 Jul 2019 10:15:05 -0700
Subject: [PATCH 6/7] back port fixing of use-after-free from RC_1_2

---
 src/socket_type.cpp  | 2 +-
 test/swarm_suite.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/socket_type.cpp b/src/socket_type.cpp
index cf38266581..cf6101fbe2 100644
--- a/src/socket_type.cpp
+++ b/src/socket_type.cpp
@@ -167,7 +167,7 @@ namespace libtorrent
 #define MAYBE_ASIO_DEBUGGING
 #endif
 
-	char const buffer[] = "";
+	static char const buffer[] = "";
 	// chasing the async_shutdown by a write is a trick to close the socket as
 	// soon as we've sent the close_notify, without having to wait to receive a
 	// response from the other end
diff --git a/test/swarm_suite.cpp b/test/swarm_suite.cpp
index 51ede5a997..fe0e8843b0 100644
--- a/test/swarm_suite.cpp
+++ b/test/swarm_suite.cpp
@@ -170,8 +170,8 @@ void test_swarm(int flags)
 	TEST_CHECK(tor2.status().is_seeding);
 	TEST_CHECK(tor3.status().is_seeding);
 
-	float average2 = sum_dl_rate2 / float(count_dl_rates2);
-	float average3 = sum_dl_rate3 / float(count_dl_rates3);
+	float average2 = count_dl_rates2 ? sum_dl_rate2 / float(count_dl_rates2) : 0.f;
+	float average3 = count_dl_rates3 ? sum_dl_rate3 / float(count_dl_rates3) : 0.f;
 
 	std::cerr << average2 << std::endl;
 	std::cerr << "average rate: " << (average2 / 1000.f) << "kB/s - "

From 84f10d05caff0d20213280951752797d166e1759 Mon Sep 17 00:00:00 2001
From: Arvid Norberg <arvid@cs.umu.se>
Date: Mon, 29 Jul 2019 22:11:54 -0700
Subject: [PATCH 7/7] back port fix to chunked http header validation

---
 src/http_parser.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/http_parser.cpp b/src/http_parser.cpp
index 16ddc48339..7f5775a81c 100644
--- a/src/http_parser.cpp
+++ b/src/http_parser.cpp
@@ -373,7 +373,8 @@ namespace libtorrent
 					int header_size;
 					if (parse_chunk_header(buf, &chunk_size, &header_size))
 					{
-						if (chunk_size < 0)
+						if (chunk_size < 0
+							|| chunk_size > std::numeric_limits<boost::int64_t>::max() - m_cur_chunk_end - header_size)
 						{
 							m_state = error_state;
 							error = true;
