support arbitrarily long magnet URIs in make_magnet_uri

This commit is contained in:
Arvid Norberg 2013-04-27 22:35:06 +00:00
parent a187d09bbf
commit 246826ecb4
2 changed files with 28 additions and 22 deletions

View File

@ -44,25 +44,25 @@ namespace libtorrent
{ {
if (!handle.is_valid()) return ""; if (!handle.is_valid()) return "";
char ret[2048]; std::string ret;
sha1_hash const& ih = handle.info_hash(); sha1_hash const& ih = handle.info_hash();
int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" ret += "magnet:?xt=urn:btih:";
, to_hex(ih.to_string()).c_str()); ret += to_hex(ih.to_string());
torrent_status st = handle.status(torrent_handle::query_name); torrent_status st = handle.status(torrent_handle::query_name);
std::string name = st.name;
if (!name.empty() && sizeof(ret) - 5 > num_chars) if (!st.name.empty())
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" {
, escape_string(name.c_str(), name.length()).c_str()); ret += "&dn=";
ret += escape_string(st.name.c_str(), st.name.length());
}
std::vector<announce_entry> const& tr = handle.trackers(); std::vector<announce_entry> const& tr = handle.trackers();
for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i) for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
{ {
if (num_chars >= sizeof(ret)) break; ret += "&tr=";
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" ret += escape_string(i->url.c_str(), i->url.length());
, escape_string(i->url.c_str(), i->url.length()).c_str());
} }
return ret; return ret;
@ -70,23 +70,25 @@ namespace libtorrent
std::string make_magnet_uri(torrent_info const& info) std::string make_magnet_uri(torrent_info const& info)
{ {
char ret[2048]; std::string ret;
sha1_hash const& ih = info.info_hash(); sha1_hash const& ih = info.info_hash();
int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" ret += "magnet:?xt=urn:btih:";
, to_hex(ih.to_string()).c_str()); ret += to_hex(ih.to_string());
std::string const& name = info.name(); std::string const& name = info.name();
if (!name.empty() && sizeof(ret) - 5 > num_chars) if (!name.empty())
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" {
, escape_string(name.c_str(), name.length()).c_str()); ret += "&dn=";
ret += escape_string(name.c_str(), name.length());
}
std::vector<announce_entry> const& tr = info.trackers(); std::vector<announce_entry> const& tr = info.trackers();
for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i) for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
{ {
if (num_chars >= sizeof(ret)) break; ret += "&tr=";
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" ret += escape_string(i->url.c_str(), i->url.length());
, escape_string(i->url.c_str(), i->url.length()).c_str());
} }
return ret; return ret;

View File

@ -1385,8 +1385,11 @@ int test_main()
"abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij012345.txt"; "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij012345.txt";
std::string comparison = test; std::string comparison = test;
trim_path_element(test); trim_path_element(test);
comparison.resize(TORRENT_MAX_PATH - 4); if (comparison.size() > TORRENT_MAX_PATH)
comparison += ".txt"; // the extension is supposed to be preserved {
comparison.resize(TORRENT_MAX_PATH - 4);
comparison += ".txt"; // the extension is supposed to be preserved
}
TEST_EQUAL(test, comparison); TEST_EQUAL(test, comparison);
// extensions > 15 characters are ignored // extensions > 15 characters are ignored
@ -1403,7 +1406,8 @@ int test_main()
"abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij.123456789abcdefghij0123456789"; "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij.123456789abcdefghij0123456789";
comparison = test; comparison = test;
trim_path_element(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); TEST_EQUAL(test, comparison);