fix bug in parse_magnet_uri and improve unit test

This commit is contained in:
arvidn 2015-10-01 01:05:00 -04:00
parent c56e878ff4
commit c1955ecb18
2 changed files with 196 additions and 120 deletions

View File

@ -251,7 +251,21 @@ namespace libtorrent
sha1_hash info_hash;
if (btih.size() == 40 + 9) from_hex(&btih[9], 40, info_hash.data());
else info_hash.assign(base32decode(btih.substr(9)));
else if (btih.size() == 32 + 9)
{
std::string ih = base32decode(btih.substr(9));
if (ih.size() != 20)
{
ec = errors::invalid_info_hash;
return;
}
info_hash.assign(ih);
}
else
{
ec = errors::invalid_info_hash;
return;
}
p.info_hash = info_hash;
if (!name.empty()) p.name = name;

View File

@ -59,11 +59,21 @@ void test_remove_url(std::string url)
TEST_EQUAL(handles.size(), 0);
}
TORRENT_TEST(remove_url)
{
test_remove_url("magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567");
}
TORRENT_TEST(remove_url2)
{
test_remove_url("http://non-existent.com/test.torrent");
}
TORRENT_TEST(magnet)
{
session_proxy p1;
session_proxy p2;
{
// test session state load/restore
settings_pack pack;
pack.set_str(settings_pack::user_agent, "test");
@ -73,11 +83,10 @@ TORRENT_TEST(magnet)
pack.set_int(settings_pack::initial_picker_threshold, 351);
pack.set_bool(settings_pack::upnp_ignore_nonrouters, true);
pack.set_bool(settings_pack::coalesce_writes, true);
pack.set_int(settings_pack::auto_scrape_interval, 753);
pack.set_bool(settings_pack::close_redundant_connections, false);
pack.set_int(settings_pack::auto_scrape_interval, 235);
pack.set_int(settings_pack::auto_scrape_min_interval, 62);
lt::session* s = new lt::session(pack);
boost::scoped_ptr<lt::session> s(new lt::session(pack));
TEST_EQUAL(pack.get_str(settings_pack::user_agent), "test");
TEST_EQUAL(pack.get_int(settings_pack::tracker_receive_timeout), 1234);
@ -167,8 +176,7 @@ TORRENT_TEST(magnet)
TEST_EQUAL(to_hex(t.info_hash().to_string()), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd");
p1 = s->abort();
delete s;
s = new lt::session();
s.reset(new lt::session());
std::vector<char> buf;
bencode(std::back_inserter(buf), session_state);
@ -178,34 +186,6 @@ TORRENT_TEST(magnet)
fprintf(stderr, "session_state\n%s\n", print_entry(session_state2).c_str());
// parse_magnet_uri
parse_magnet_uri("magnet:?dn=foo&dht=127.0.0.1:43", p, ec);
TEST_CHECK(ec == error_code(errors::missing_info_hash_in_uri));
ec.clear();
// parse_magnet_uri
parse_magnet_uri("magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd&ws=http://foo.com/bar&ws=http://bar.com/foo", p, ec);
TEST_CHECK(!ec);
TEST_EQUAL(p.url_seeds.size(), 2);
TEST_EQUAL(p.url_seeds[0], "http://foo.com/bar");
TEST_EQUAL(p.url_seeds[1], "http://bar.com/foo");
ec.clear();
parse_magnet_uri("magnet:?xt=blah&dn=foo&dht=127.0.0.1:43", p, ec);
TEST_CHECK(ec == error_code(errors::missing_info_hash_in_uri));
ec.clear();
#ifndef TORRENT_DISABLE_DHT
parse_magnet_uri("magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd&dn=foo&dht=127.0.0.1:43", p, ec);
TEST_CHECK(!ec);
if (ec) fprintf(stderr, "%s\n", ec.message().c_str());
ec.clear();
TEST_CHECK(p.dht_nodes.size() == 1);
TEST_CHECK(p.dht_nodes[0].first == "127.0.0.1");
TEST_CHECK(p.dht_nodes[0].second == 43);
#endif
// make sure settings that haven't been changed from their defaults are not saved
TEST_CHECK(session_state2.dict_find("settings")
.dict_find("optimistic_disk_retry") == 0);
@ -222,93 +202,175 @@ TORRENT_TEST(magnet)
CMP_SET(urlseed_wait_retry);
CMP_SET(initial_picker_threshold);
CMP_SET(auto_scrape_interval);
CMP_SET(auto_scrape_interval);
CMP_SET(auto_scrape_min_interval);
p2 = s->abort();
delete s;
}
// make_magnet_uri
{
entry info;
info["pieces"] = "aaaaaaaaaaaaaaaaaaaa";
info["name"] = "slightly shorter name, it's kind of sad that people started the trend of incorrectly encoding the regular name field and then adding another one with correct encoding";
info["name.utf-8"] = "this is a long ass name in order to try to make make_magnet_uri overflow and hopefully crash. Although, by the time you read this that particular bug should have been fixed";
info["piece length"] = 16 * 1024;
info["length"] = 3245;
entry torrent;
torrent["info"] = info;
entry::list_type& al1 = torrent["announce-list"].list();
al1.push_back(entry::list_type());
entry::list_type& al = al1.back().list();
al.push_back(entry("http://bigtorrent.org:2710/announce"));
al.push_back(entry("http://bt.careland.com.cn:6969/announce"));
al.push_back(entry("http://bt.e-burg.org:2710/announce"));
al.push_back(entry("http://bttrack.9you.com/announce"));
al.push_back(entry("http://coppersurfer.tk:6969/announce"));
al.push_back(entry("http://erdgeist.org/arts/software/opentracker/announce"));
al.push_back(entry("http://exodus.desync.com/announce"));
al.push_back(entry("http://fr33dom.h33t.com:3310/announce"));
al.push_back(entry("http://genesis.1337x.org:1337/announce"));
al.push_back(entry("http://inferno.demonoid.me:3390/announce"));
al.push_back(entry("http://inferno.demonoid.ph:3390/announce"));
al.push_back(entry("http://ipv6.tracker.harry.lu/announce"));
al.push_back(entry("http://lnxroot.com:6969/announce"));
al.push_back(entry("http://nemesis.1337x.org/announce"));
al.push_back(entry("http://puto.me:6969/announce"));
al.push_back(entry("http://sline.net:2710/announce"));
al.push_back(entry("http://tracker.beeimg.com:6969/announce"));
al.push_back(entry("http://tracker.ccc.de/announce"));
al.push_back(entry("http://tracker.coppersurfer.tk/announce"));
al.push_back(entry("http://tracker.coppersurfer.tk:6969/announce"));
al.push_back(entry("http://tracker.cpleft.com:2710/announce"));
al.push_back(entry("http://tracker.istole.it/announce"));
al.push_back(entry("http://tracker.kamyu.net/announce"));
al.push_back(entry("http://tracker.novalayer.org:6969/announce"));
al.push_back(entry("http://tracker.torrent.to:2710/announce"));
al.push_back(entry("http://tracker.torrentbay.to:6969/announce"));
al.push_back(entry("udp://tracker.openbittorrent.com:80"));
al.push_back(entry("udp://tracker.publicbt.com:80"));
std::vector<char> buf;
bencode(std::back_inserter(buf), torrent);
buf.push_back('\0');
printf("%s\n", &buf[0]);
error_code ec;
torrent_info ti(&buf[0], buf.size(), ec);
TEST_EQUAL(al.size(), ti.trackers().size());
std::string magnet = make_magnet_uri(ti);
printf("%s len: %d\n", magnet.c_str(), int(magnet.size()));
}
// make_magnet_uri
{
entry info;
info["pieces"] = "aaaaaaaaaaaaaaaaaaaa";
info["name"] = "test";
info["name.utf-8"] = "test";
info["piece length"] = 16 * 1024;
info["length"] = 3245;
entry torrent;
torrent["info"] = info;
torrent["url-list"] = "http://foo.com/bar";
std::vector<char> buf;
bencode(std::back_inserter(buf), torrent);
buf.push_back('\0');
printf("%s\n", &buf[0]);
error_code ec;
torrent_info ti(&buf[0], buf.size(), ec);
std::string magnet = make_magnet_uri(ti);
printf("%s len: %d\n", magnet.c_str(), int(magnet.size()));
TEST_CHECK(magnet.find("&ws=http%3a%2f%2ffoo.com%2fbar") != std::string::npos);
}
test_remove_url("magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567");
test_remove_url("http://non-existent.com/test.torrent");
}
TORRENT_TEST(parse_missing_hash)
{
// parse_magnet_uri
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?dn=foo&dht=127.0.0.1:43", p, ec);
TEST_EQUAL(ec, error_code(errors::missing_info_hash_in_uri));
ec.clear();
}
TORRENT_TEST(parse_base32_hash)
{
// parse_magnet_uri
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih:MFRGCYTBMJQWEYLCMFRGCYTBMJQWEYLC", p, ec);
TEST_CHECK(!ec);
TEST_EQUAL(p.info_hash, sha1_hash("abababababababababab"));
ec.clear();
}
TORRENT_TEST(parse_web_seeds)
{
// parse_magnet_uri
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd&ws=http://foo.com/bar&ws=http://bar.com/foo", p, ec);
TEST_CHECK(!ec);
TEST_EQUAL(p.url_seeds.size(), 2);
TEST_EQUAL(p.url_seeds[0], "http://foo.com/bar");
TEST_EQUAL(p.url_seeds[1], "http://bar.com/foo");
ec.clear();
}
TORRENT_TEST(parse_missing_hash2)
{
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=blah&dn=foo&dht=127.0.0.1:43", p, ec);
TEST_EQUAL(ec, error_code(errors::missing_info_hash_in_uri));
ec.clear();
}
TORRENT_TEST(parse_short_hash)
{
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih:abababab", p, ec);
TEST_EQUAL(ec, error_code(errors::invalid_info_hash));
ec.clear();
}
TORRENT_TEST(parse_long_hash)
{
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih:ababababababababababab", p, ec);
TEST_EQUAL(ec, error_code(errors::invalid_info_hash));
ec.clear();
}
TORRENT_TEST(parse_space_hash)
{
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih: abababababababababab", p, ec);
TEST_EQUAL(ec, error_code(errors::invalid_info_hash));
ec.clear();
}
#ifndef TORRENT_DISABLE_DHT
TORRENT_TEST(parse_dht_node)
{
error_code ec;
add_torrent_params p;
parse_magnet_uri("magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd&dn=foo&dht=127.0.0.1:43", p, ec);
TEST_CHECK(!ec);
if (ec) fprintf(stderr, "%s\n", ec.message().c_str());
ec.clear();
TEST_EQUAL(p.dht_nodes.size(), 1);
TEST_EQUAL(p.dht_nodes[0].first, "127.0.0.1");
TEST_EQUAL(p.dht_nodes[0].second, 43);
}
#endif
TORRENT_TEST(make_magnet_uri)
{
// make_magnet_uri
entry info;
info["pieces"] = "aaaaaaaaaaaaaaaaaaaa";
info["name"] = "slightly shorter name, it's kind of sad that people started the trend of incorrectly encoding the regular name field and then adding another one with correct encoding";
info["name.utf-8"] = "this is a long ass name in order to try to make make_magnet_uri overflow and hopefully crash. Although, by the time you read this that particular bug should have been fixed";
info["piece length"] = 16 * 1024;
info["length"] = 3245;
entry torrent;
torrent["info"] = info;
entry::list_type& al1 = torrent["announce-list"].list();
al1.push_back(entry::list_type());
entry::list_type& al = al1.back().list();
al.push_back(entry("http://bigtorrent.org:2710/announce"));
al.push_back(entry("http://bt.careland.com.cn:6969/announce"));
al.push_back(entry("http://bt.e-burg.org:2710/announce"));
al.push_back(entry("http://bttrack.9you.com/announce"));
al.push_back(entry("http://coppersurfer.tk:6969/announce"));
al.push_back(entry("http://erdgeist.org/arts/software/opentracker/announce"));
al.push_back(entry("http://exodus.desync.com/announce"));
al.push_back(entry("http://fr33dom.h33t.com:3310/announce"));
al.push_back(entry("http://genesis.1337x.org:1337/announce"));
al.push_back(entry("http://inferno.demonoid.me:3390/announce"));
al.push_back(entry("http://inferno.demonoid.ph:3390/announce"));
al.push_back(entry("http://ipv6.tracker.harry.lu/announce"));
al.push_back(entry("http://lnxroot.com:6969/announce"));
al.push_back(entry("http://nemesis.1337x.org/announce"));
al.push_back(entry("http://puto.me:6969/announce"));
al.push_back(entry("http://sline.net:2710/announce"));
al.push_back(entry("http://tracker.beeimg.com:6969/announce"));
al.push_back(entry("http://tracker.ccc.de/announce"));
al.push_back(entry("http://tracker.coppersurfer.tk/announce"));
al.push_back(entry("http://tracker.coppersurfer.tk:6969/announce"));
al.push_back(entry("http://tracker.cpleft.com:2710/announce"));
al.push_back(entry("http://tracker.istole.it/announce"));
al.push_back(entry("http://tracker.kamyu.net/announce"));
al.push_back(entry("http://tracker.novalayer.org:6969/announce"));
al.push_back(entry("http://tracker.torrent.to:2710/announce"));
al.push_back(entry("http://tracker.torrentbay.to:6969/announce"));
al.push_back(entry("udp://tracker.openbittorrent.com:80"));
al.push_back(entry("udp://tracker.publicbt.com:80"));
std::vector<char> buf;
bencode(std::back_inserter(buf), torrent);
buf.push_back('\0');
printf("%s\n", &buf[0]);
error_code ec;
torrent_info ti(&buf[0], buf.size(), ec);
TEST_EQUAL(al.size(), ti.trackers().size());
std::string magnet = make_magnet_uri(ti);
printf("%s len: %d\n", magnet.c_str(), int(magnet.size()));
}
TORRENT_TEST(make_magnet_uri2)
{
// make_magnet_uri
entry info;
info["pieces"] = "aaaaaaaaaaaaaaaaaaaa";
info["name"] = "test";
info["name.utf-8"] = "test";
info["piece length"] = 16 * 1024;
info["length"] = 3245;
entry torrent;
torrent["info"] = info;
torrent["url-list"] = "http://foo.com/bar";
std::vector<char> buf;
bencode(std::back_inserter(buf), torrent);
buf.push_back('\0');
printf("%s\n", &buf[0]);
error_code ec;
torrent_info ti(&buf[0], buf.size(), ec);
std::string magnet = make_magnet_uri(ti);
printf("%s len: %d\n", magnet.c_str(), int(magnet.size()));
TEST_CHECK(magnet.find("&ws=http%3a%2f%2ffoo.com%2fbar") != std::string::npos);
}