From 246826ecb4d2dcb99418ce67cd927a0df46243ab Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 27 Apr 2013 22:35:06 +0000 Subject: [PATCH] support arbitrarily long magnet URIs in make_magnet_uri --- src/magnet_uri.cpp | 40 +++++++++++++++++++++------------------- test/test_primitives.cpp | 10 +++++++--- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/magnet_uri.cpp b/src/magnet_uri.cpp index e54ba4b37..7644bc8e0 100644 --- a/src/magnet_uri.cpp +++ b/src/magnet_uri.cpp @@ -44,25 +44,25 @@ namespace libtorrent { if (!handle.is_valid()) return ""; - char ret[2048]; + std::string ret; sha1_hash const& ih = handle.info_hash(); - int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" - , to_hex(ih.to_string()).c_str()); + ret += "magnet:?xt=urn:btih:"; + ret += to_hex(ih.to_string()); torrent_status st = handle.status(torrent_handle::query_name); - std::string name = st.name; - if (!name.empty() && sizeof(ret) - 5 > num_chars) - num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" - , escape_string(name.c_str(), name.length()).c_str()); + if (!st.name.empty()) + { + ret += "&dn="; + ret += escape_string(st.name.c_str(), st.name.length()); + } std::vector const& tr = handle.trackers(); for (std::vector::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i) { - if (num_chars >= sizeof(ret)) break; - num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" - , escape_string(i->url.c_str(), i->url.length()).c_str()); + ret += "&tr="; + ret += escape_string(i->url.c_str(), i->url.length()); } return ret; @@ -70,23 +70,25 @@ namespace libtorrent std::string make_magnet_uri(torrent_info const& info) { - char ret[2048]; + std::string ret; sha1_hash const& ih = info.info_hash(); - int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" - , to_hex(ih.to_string()).c_str()); + ret += "magnet:?xt=urn:btih:"; + ret += to_hex(ih.to_string()); std::string const& name = info.name(); - if (!name.empty() && sizeof(ret) - 5 > num_chars) - num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" - , escape_string(name.c_str(), name.length()).c_str()); + if (!name.empty()) + { + ret += "&dn="; + ret += escape_string(name.c_str(), name.length()); + } std::vector const& tr = info.trackers(); + for (std::vector::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i) { - if (num_chars >= sizeof(ret)) break; - num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" - , escape_string(i->url.c_str(), i->url.length()).c_str()); + ret += "&tr="; + ret += escape_string(i->url.c_str(), i->url.length()); } return ret; diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 133860fc6..a3f7e7ce2 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -1385,8 +1385,11 @@ int test_main() "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij012345.txt"; std::string comparison = test; trim_path_element(test); - comparison.resize(TORRENT_MAX_PATH - 4); - comparison += ".txt"; // the extension is supposed to be preserved + if (comparison.size() > TORRENT_MAX_PATH) + { + comparison.resize(TORRENT_MAX_PATH - 4); + comparison += ".txt"; // the extension is supposed to be preserved + } TEST_EQUAL(test, comparison); // extensions > 15 characters are ignored @@ -1403,7 +1406,8 @@ int test_main() "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij.123456789abcdefghij0123456789"; comparison = test; trim_path_element(test); - comparison.resize(TORRENT_MAX_PATH); + if (comparison.size() > TORRENT_MAX_PATH) + comparison.resize(TORRENT_MAX_PATH); TEST_EQUAL(test, comparison);