diff --git a/CMakeLists.txt b/CMakeLists.txt index 280de15ae..b8c1765b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,6 +327,8 @@ if(build_tests) test_string test_primitives test_http_parser + test_packet_buffer + test_magnet test_ip_filter test_hasher test_metadata_extension diff --git a/test/Jamfile b/test/Jamfile index c51fb4bfa..1dd7df85d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -71,7 +71,9 @@ test-suite libtorrent : [ run test_fast_extension.cpp ] [ run test_primitives.cpp ] [ run test_http_parser.cpp ] + [ run test_packet_buffer.cpp ] [ run test_string.cpp ] + [ run test_magnet.cpp ] [ run test_xml.cpp ] [ run test_ip_filter.cpp ] [ run test_hasher.cpp ] diff --git a/test/Makefile.am b/test/Makefile.am index 0bb3d804d..f9ab02b81 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,6 +23,8 @@ test_programs = \ test_string \ test_primitives \ test_http_parser \ + test_magnet \ + test_packet_buffer \ test_rss \ test_storage \ test_swarm \ diff --git a/test/test_magnet.cpp b/test/test_magnet.cpp new file mode 100644 index 000000000..e3a71646d --- /dev/null +++ b/test/test_magnet.cpp @@ -0,0 +1,268 @@ +/* + +Copyright (c) 2012, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "test.hpp" +#include "libtorrent/magnet_uri.hpp" +#include "libtorrent/session.hpp" +#include "libtorrent/torrent_handle.hpp" +#include "libtorrent/bencode.hpp" + +using namespace libtorrent; + +int test_main() +{ + session_proxy p1; + session_proxy p2; + { + // test session state load/restore + session* s = new session(fingerprint("LT",0,0,0,0), 0); + + session_settings sett; + sett.user_agent = "test"; + sett.tracker_receive_timeout = 1234; + sett.file_pool_size = 543; + sett.urlseed_wait_retry = 74; + sett.file_pool_size = 754; + sett.initial_picker_threshold = 351; + sett.upnp_ignore_nonrouters = 5326; + sett.coalesce_writes = 623; + sett.auto_scrape_interval = 753; + sett.close_redundant_connections = 245; + sett.auto_scrape_interval = 235; + sett.auto_scrape_min_interval = 62; + s->set_settings(sett); + +#ifndef TORRENT_DISABLE_DHT + dht_settings dhts; + dhts.max_peers_reply = 70; + s->set_dht_settings(dhts); +#endif +/* +#ifndef TORRENT_DISABLE_DHT + dht_settings dht_sett; + s->set_dht_settings(dht_sett); +#endif +*/ + entry session_state; + s->save_state(session_state); + + // test magnet link parsing + add_torrent_params p; + p.save_path = "."; + error_code ec; + p.url = "magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "&tr=http://1" + "&tr=http://2" + "&tr=http://3" + "&dn=foo" + "&dht=127.0.0.1:43"; + torrent_handle t = s->add_torrent(p, ec); + TEST_CHECK(!ec); + if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); + + std::vector trackers = t.trackers(); + TEST_EQUAL(trackers.size(), 3); + std::set trackers_set; + for (std::vector::iterator i = trackers.begin() + , end(trackers.end()); i != end; ++i) + trackers_set.insert(i->url); + + + TEST_CHECK(trackers_set.count("http://1") == 1); + TEST_CHECK(trackers_set.count("http://2") == 1); + TEST_CHECK(trackers_set.count("http://3") == 1); + + p.url = "magnet:" + "?tr=http://1" + "&tr=http://2" + "&dn=foo" + "&dht=127.0.0.1:43" + "&xt=urn:btih:c352cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"; + torrent_handle t2 = s->add_torrent(p, ec); + TEST_CHECK(!ec); + if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); + + trackers = t2.trackers(); + TEST_EQUAL(trackers.size(), 2); + + p.url = "magnet:" + "?tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80" + "&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80" + "&tr=udp%3A%2F%2Ftracker.ccc.de%3A80" + "&xt=urn:btih:a38d02c287893842a32825aa866e00828a318f07" + "&dn=Ubuntu+11.04+%28Final%29"; + torrent_handle t3 = s->add_torrent(p, ec); + TEST_CHECK(!ec); + if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); + + trackers = t3.trackers(); + TEST_EQUAL(trackers.size(), 3); + if (trackers.size() > 0) + { + TEST_EQUAL(trackers[0].url, "udp://tracker.openbittorrent.com:80"); + fprintf(stderr, "1: %s\n", trackers[0].url.c_str()); + } + if (trackers.size() > 1) + { + TEST_EQUAL(trackers[1].url, "udp://tracker.publicbt.com:80"); + fprintf(stderr, "2: %s\n", trackers[1].url.c_str()); + } + if (trackers.size() > 2) + { + TEST_EQUAL(trackers[2].url, "udp://tracker.ccc.de:80"); + fprintf(stderr, "3: %s\n", trackers[2].url.c_str()); + } + + TEST_EQUAL(to_hex(t.info_hash().to_string()), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"); + + p1 = s->abort(); + delete s; + s = new session(fingerprint("LT",0,0,0,0), 0); + + std::vector buf; + bencode(std::back_inserter(buf), session_state); + lazy_entry session_state2; + int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), session_state2, ec); + TEST_CHECK(ret == 0); + + 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("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); + + s->load_state(session_state2); +#define CMP_SET(x) TEST_CHECK(s->settings().x == sett.x) + + CMP_SET(user_agent); + CMP_SET(tracker_receive_timeout); + CMP_SET(file_pool_size); + CMP_SET(urlseed_wait_retry); + CMP_SET(file_pool_size); + CMP_SET(initial_picker_threshold); + CMP_SET(upnp_ignore_nonrouters); + CMP_SET(coalesce_writes); + CMP_SET(auto_scrape_interval); + CMP_SET(close_redundant_connections); + CMP_SET(auto_scrape_interval); + CMP_SET(auto_scrape_min_interval); + CMP_SET(max_peerlist_size); + CMP_SET(max_paused_peerlist_size); + CMP_SET(min_announce_interval); + CMP_SET(prioritize_partial_pieces); + CMP_SET(auto_manage_startup); + CMP_SET(rate_limit_ip_overhead); + CMP_SET(announce_to_all_trackers); + CMP_SET(announce_to_all_tiers); + CMP_SET(prefer_udp_trackers); + CMP_SET(strict_super_seeding); + CMP_SET(seeding_piece_quota); + 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 buf; + bencode(std::back_inserter(buf), torrent); + 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())); + } + + + return 0; +} + diff --git a/test/test_packet_buffer.cpp b/test/test_packet_buffer.cpp new file mode 100644 index 000000000..dc761f6cd --- /dev/null +++ b/test/test_packet_buffer.cpp @@ -0,0 +1,163 @@ +/* + +Copyright (c) 2012, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "test.hpp" +#include "libtorrent/packet_buffer.hpp" + +using libtorrent::packet_buffer; + +int test_main() +{ + // test packet_buffer + { + packet_buffer pb; + + TEST_EQUAL(pb.capacity(), 0); + TEST_EQUAL(pb.size(), 0); + TEST_EQUAL(pb.span(), 0); + + pb.insert(123, (void*)123); + TEST_EQUAL(pb.at(123 + 16), 0); + + TEST_CHECK(pb.at(123) == (void*)123); + TEST_CHECK(pb.capacity() > 0); + TEST_EQUAL(pb.size(), 1); + TEST_EQUAL(pb.span(), 1); + TEST_EQUAL(pb.cursor(), 123); + + pb.insert(125, (void*)125); + + TEST_CHECK(pb.at(125) == (void*)125); + TEST_EQUAL(pb.size(), 2); + TEST_EQUAL(pb.span(), 3); + TEST_EQUAL(pb.cursor(), 123); + + pb.insert(500, (void*)500); + TEST_EQUAL(pb.size(), 3); + TEST_EQUAL(pb.span(), 501 - 123); + TEST_EQUAL(pb.capacity(), 512); + + pb.insert(500, (void*)501); + TEST_EQUAL(pb.size(), 3); + pb.insert(500, (void*)500); + TEST_EQUAL(pb.size(), 3); + + TEST_CHECK(pb.remove(123) == (void*)123); + TEST_EQUAL(pb.size(), 2); + TEST_EQUAL(pb.span(), 501 - 125); + TEST_EQUAL(pb.cursor(), 125); + TEST_CHECK(pb.remove(125) == (void*)125); + TEST_EQUAL(pb.size(), 1); + TEST_EQUAL(pb.span(), 1); + TEST_EQUAL(pb.cursor(), 500); + + TEST_CHECK(pb.remove(500) == (void*)500); + TEST_EQUAL(pb.size(), 0); + TEST_EQUAL(pb.span(), 0); + + for (int i = 0; i < 0xff; ++i) + { + int index = (i + 0xfff0) & 0xffff; + pb.insert(index, (void*)(index + 1)); + fprintf(stderr, "insert: %u (mask: %x)\n", index, int(pb.capacity() - 1)); + TEST_EQUAL(pb.capacity(), 512); + if (i >= 14) + { + index = (index - 14) & 0xffff; + fprintf(stderr, "remove: %u\n", index); + TEST_CHECK(pb.remove(index) == (void*)(index + 1)); + TEST_EQUAL(pb.size(), 14); + } + } + } + + { + // test wrapping the indices + packet_buffer pb; + + TEST_EQUAL(pb.size(), 0); + + pb.insert(0xfffe, (void*)1); + TEST_CHECK(pb.at(0xfffe) == (void*)1); + + pb.insert(2, (void*)2); + TEST_CHECK(pb.at(2) == (void*)2); + + pb.remove(0xfffe); + TEST_CHECK(pb.at(0xfffe) == (void*)0); + TEST_CHECK(pb.at(2) == (void*)2); + } + + { + // test wrapping the indices + packet_buffer pb; + + TEST_EQUAL(pb.size(), 0); + + pb.insert(0xfff3, (void*)1); + TEST_CHECK(pb.at(0xfff3) == (void*)1); + + int new_index = (0xfff3 + pb.capacity()) & 0xffff; + pb.insert(new_index, (void*)2); + TEST_CHECK(pb.at(new_index) == (void*)2); + + void* old = pb.remove(0xfff3); + TEST_CHECK(old == (void*)1); + TEST_CHECK(pb.at(0xfff3) == (void*)0); + TEST_CHECK(pb.at(new_index) == (void*)2); + } + + { + // test wrapping the indices backwards + packet_buffer pb; + + TEST_EQUAL(pb.size(), 0); + + pb.insert(0xfff3, (void*)1); + TEST_CHECK(pb.at(0xfff3) == (void*)1); + + int new_index = (0xfff3 + pb.capacity()) & 0xffff; + pb.insert(new_index, (void*)2); + TEST_CHECK(pb.at(new_index) == (void*)2); + + void* old = pb.remove(0xfff3); + TEST_CHECK(old == (void*)1); + TEST_CHECK(pb.at(0xfff3) == (void*)0); + TEST_CHECK(pb.at(new_index) == (void*)2); + + pb.insert(0xffff, (void*)0xffff); + } + + + return 0; +} + diff --git a/test/test_pe_crypto.cpp b/test/test_pe_crypto.cpp index 4b697ca84..70c159fe6 100644 --- a/test/test_pe_crypto.cpp +++ b/test/test_pe_crypto.cpp @@ -162,9 +162,13 @@ void test_enc_handler(libtorrent::encryption_handler* a, libtorrent::encryption_ } } +#endif + int test_main() { using namespace libtorrent; + +#ifndef TORRENT_DISABLE_ENCRYPTION int repcount = 128; for (int rep = 0; rep < repcount; ++rep) @@ -206,17 +210,36 @@ int test_main() test_transfer(pe_settings::enabled, pe_settings::rc4); test_transfer(pe_settings::enabled, pe_settings::both, false); test_transfer(pe_settings::enabled, pe_settings::both, true); - - return 0; -} - #else - -int test_main() -{ fprintf(stderr, "PE test not run because it's disabled\n"); - return 0; -} - #endif +#if defined TORRENT_USE_OPENSSL + // test sign_rsa and verify_rsa + char private_key[1192]; + int private_len = sizeof(private_key); + char public_key[268]; + int public_len = sizeof(public_key); + + ret = generate_rsa_keys(public_key, &public_len, private_key, &private_len, 2048); + fprintf(stderr, "keysizes: pub: %d priv: %d\n", public_len, private_len); + + TEST_CHECK(ret); + + char test_message[1024]; + std::generate(test_message, test_message + 1024, &std::rand); + + char signature[256]; + int sig_len = sign_rsa(hasher(test_message, sizeof(test_message)).final() + , private_key, private_len, signature, sizeof(signature)); + + TEST_CHECK(sig_len == 256); + + ret = verify_rsa(hasher(test_message, sizeof(test_message)).final() + , public_key, public_len, signature, sig_len); + TEST_CHECK(ret == 1); +#endif + + return 0; +} + diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index f05654d31..8c1e3efb3 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -41,7 +41,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/broadcast_socket.hpp" #include "libtorrent/identify_client.hpp" #include "libtorrent/file.hpp" -#include "libtorrent/packet_buffer.hpp" #include "libtorrent/session.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/timestamp_history.hpp" @@ -59,10 +58,6 @@ POSSIBILITY OF SUCH DAMAGE. using namespace libtorrent; -namespace libtorrent { - TORRENT_EXPORT std::string sanitize_path(std::string const& p); -} - sha1_hash to_hash(char const* s) { sha1_hash ret; @@ -70,12 +65,6 @@ sha1_hash to_hash(char const* s) return ret; } -namespace libtorrent -{ - // defined in torrent_info.cpp - TORRENT_EXPORT bool verify_encoding(std::string& target, bool path = true); -} - address rand_v4() { return address_v4((rand() << 16 | rand()) & 0xffffffff); @@ -113,32 +102,6 @@ int test_main() } fprintf(stderr, "\n"); -#if defined TORRENT_USE_OPENSSL - // test sign_rsa and verify_rsa - char private_key[1192]; - int private_len = sizeof(private_key); - char public_key[268]; - int public_len = sizeof(public_key); - - ret = generate_rsa_keys(public_key, &public_len, private_key, &private_len, 2048); - fprintf(stderr, "keysizes: pub: %d priv: %d\n", public_len, private_len); - - TEST_CHECK(ret); - - char test_message[1024]; - std::generate(test_message, test_message + 1024, &std::rand); - - char signature[256]; - int sig_len = sign_rsa(hasher(test_message, sizeof(test_message)).final() - , private_key, private_len, signature, sizeof(signature)); - - TEST_CHECK(sig_len == 256); - - ret = verify_rsa(hasher(test_message, sizeof(test_message)).final() - , public_key, public_len, signature, sig_len); - TEST_CHECK(ret == 1); -#endif - // test external ip voting external_ip ipv1; @@ -234,126 +197,6 @@ int test_main() // TODO: test the case where a sample is lower than the history entry but not lower than the base } - // test packet_buffer - { - packet_buffer pb; - - TEST_EQUAL(pb.capacity(), 0); - TEST_EQUAL(pb.size(), 0); - TEST_EQUAL(pb.span(), 0); - - pb.insert(123, (void*)123); - TEST_EQUAL(pb.at(123 + 16), 0); - - TEST_CHECK(pb.at(123) == (void*)123); - TEST_CHECK(pb.capacity() > 0); - TEST_EQUAL(pb.size(), 1); - TEST_EQUAL(pb.span(), 1); - TEST_EQUAL(pb.cursor(), 123); - - pb.insert(125, (void*)125); - - TEST_CHECK(pb.at(125) == (void*)125); - TEST_EQUAL(pb.size(), 2); - TEST_EQUAL(pb.span(), 3); - TEST_EQUAL(pb.cursor(), 123); - - pb.insert(500, (void*)500); - TEST_EQUAL(pb.size(), 3); - TEST_EQUAL(pb.span(), 501 - 123); - TEST_EQUAL(pb.capacity(), 512); - - pb.insert(500, (void*)501); - TEST_EQUAL(pb.size(), 3); - pb.insert(500, (void*)500); - TEST_EQUAL(pb.size(), 3); - - TEST_CHECK(pb.remove(123) == (void*)123); - TEST_EQUAL(pb.size(), 2); - TEST_EQUAL(pb.span(), 501 - 125); - TEST_EQUAL(pb.cursor(), 125); - TEST_CHECK(pb.remove(125) == (void*)125); - TEST_EQUAL(pb.size(), 1); - TEST_EQUAL(pb.span(), 1); - TEST_EQUAL(pb.cursor(), 500); - - TEST_CHECK(pb.remove(500) == (void*)500); - TEST_EQUAL(pb.size(), 0); - TEST_EQUAL(pb.span(), 0); - - for (int i = 0; i < 0xff; ++i) - { - int index = (i + 0xfff0) & 0xffff; - pb.insert(index, (void*)(index + 1)); - fprintf(stderr, "insert: %u (mask: %x)\n", index, int(pb.capacity() - 1)); - TEST_EQUAL(pb.capacity(), 512); - if (i >= 14) - { - index = (index - 14) & 0xffff; - fprintf(stderr, "remove: %u\n", index); - TEST_CHECK(pb.remove(index) == (void*)(index + 1)); - TEST_EQUAL(pb.size(), 14); - } - } - } - - { - // test wrapping the indices - packet_buffer pb; - - TEST_EQUAL(pb.size(), 0); - - pb.insert(0xfffe, (void*)1); - TEST_CHECK(pb.at(0xfffe) == (void*)1); - - pb.insert(2, (void*)2); - TEST_CHECK(pb.at(2) == (void*)2); - - pb.remove(0xfffe); - TEST_CHECK(pb.at(0xfffe) == (void*)0); - TEST_CHECK(pb.at(2) == (void*)2); - } - - { - // test wrapping the indices - packet_buffer pb; - - TEST_EQUAL(pb.size(), 0); - - pb.insert(0xfff3, (void*)1); - TEST_CHECK(pb.at(0xfff3) == (void*)1); - - int new_index = (0xfff3 + pb.capacity()) & 0xffff; - pb.insert(new_index, (void*)2); - TEST_CHECK(pb.at(new_index) == (void*)2); - - void* old = pb.remove(0xfff3); - TEST_CHECK(old == (void*)1); - TEST_CHECK(pb.at(0xfff3) == (void*)0); - TEST_CHECK(pb.at(new_index) == (void*)2); - } - - { - // test wrapping the indices backwards - packet_buffer pb; - - TEST_EQUAL(pb.size(), 0); - - pb.insert(0xfff3, (void*)1); - TEST_CHECK(pb.at(0xfff3) == (void*)1); - - int new_index = (0xfff3 + pb.capacity()) & 0xffff; - pb.insert(new_index, (void*)2); - TEST_CHECK(pb.at(new_index) == (void*)2); - - void* old = pb.remove(0xfff3); - TEST_CHECK(old == (void*)1); - TEST_CHECK(pb.at(0xfff3) == (void*)0); - TEST_CHECK(pb.at(new_index) == (void*)2); - - pb.insert(0xffff, (void*)0xffff); - } - // test error codes TEST_CHECK(error_code(errors::http_error).message() == "HTTP error"); TEST_CHECK(error_code(errors::missing_file_sizes).message() == "missing or invalid 'file sizes' entry"); @@ -365,200 +208,12 @@ int test_main() TEST_CHECK(error_code(errors::unauthorized, get_http_category()).message() == "401 Unauthorized"); TEST_CHECK(error_code(errors::service_unavailable, get_http_category()).message() == "503 Service Unavailable"); - session_proxy p1; - session_proxy p2; - { - // test session state load/restore - session* s = new session(fingerprint("LT",0,0,0,0), 0); - - session_settings sett; - sett.user_agent = "test"; - sett.tracker_receive_timeout = 1234; - sett.file_pool_size = 543; - sett.urlseed_wait_retry = 74; - sett.file_pool_size = 754; - sett.initial_picker_threshold = 351; - sett.upnp_ignore_nonrouters = 5326; - sett.coalesce_writes = 623; - sett.auto_scrape_interval = 753; - sett.close_redundant_connections = 245; - sett.auto_scrape_interval = 235; - sett.auto_scrape_min_interval = 62; - s->set_settings(sett); - -#ifndef TORRENT_DISABLE_DHT - dht_settings dhts; - dhts.max_peers_reply = 70; - s->set_dht_settings(dhts); -#endif -/* -#ifndef TORRENT_DISABLE_DHT - dht_settings dht_sett; - s->set_dht_settings(dht_sett); -#endif -*/ - entry session_state; - s->save_state(session_state); - - // test magnet link parsing - add_torrent_params p; - p.save_path = "."; - error_code ec; - p.url = "magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" - "&tr=http://1" - "&tr=http://2" - "&tr=http://3" - "&dn=foo" - "&dht=127.0.0.1:43"; - torrent_handle t = s->add_torrent(p, ec); - TEST_CHECK(!ec); - if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); - - std::vector trackers = t.trackers(); - TEST_EQUAL(trackers.size(), 3); - std::set trackers_set; - for (std::vector::iterator i = trackers.begin() - , end(trackers.end()); i != end; ++i) - trackers_set.insert(i->url); - - - TEST_CHECK(trackers_set.count("http://1") == 1); - TEST_CHECK(trackers_set.count("http://2") == 1); - TEST_CHECK(trackers_set.count("http://3") == 1); - - p.url = "magnet:" - "?tr=http://1" - "&tr=http://2" - "&dn=foo" - "&dht=127.0.0.1:43" - "&xt=urn:btih:c352cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"; - torrent_handle t2 = s->add_torrent(p, ec); - TEST_CHECK(!ec); - if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); - - trackers = t2.trackers(); - TEST_EQUAL(trackers.size(), 2); - - p.url = "magnet:" - "?tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80" - "&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80" - "&tr=udp%3A%2F%2Ftracker.ccc.de%3A80" - "&xt=urn:btih:a38d02c287893842a32825aa866e00828a318f07" - "&dn=Ubuntu+11.04+%28Final%29"; - torrent_handle t3 = s->add_torrent(p, ec); - TEST_CHECK(!ec); - if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); - - trackers = t3.trackers(); - TEST_EQUAL(trackers.size(), 3); - if (trackers.size() > 0) - { - TEST_EQUAL(trackers[0].url, "udp://tracker.openbittorrent.com:80"); - fprintf(stderr, "1: %s\n", trackers[0].url.c_str()); - } - if (trackers.size() > 1) - { - TEST_EQUAL(trackers[1].url, "udp://tracker.publicbt.com:80"); - fprintf(stderr, "2: %s\n", trackers[1].url.c_str()); - } - if (trackers.size() > 2) - { - TEST_EQUAL(trackers[2].url, "udp://tracker.ccc.de:80"); - fprintf(stderr, "3: %s\n", trackers[2].url.c_str()); - } - - TEST_EQUAL(to_hex(t.info_hash().to_string()), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"); - - p1 = s->abort(); - delete s; - s = new session(fingerprint("LT",0,0,0,0), 0); - - std::vector buf; - bencode(std::back_inserter(buf), session_state); - lazy_entry session_state2; - ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), session_state2, ec); - TEST_CHECK(ret == 0); - - 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("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); - - s->load_state(session_state2); -#define CMP_SET(x) TEST_CHECK(s->settings().x == sett.x) - - CMP_SET(user_agent); - CMP_SET(tracker_receive_timeout); - CMP_SET(file_pool_size); - CMP_SET(urlseed_wait_retry); - CMP_SET(file_pool_size); - CMP_SET(initial_picker_threshold); - CMP_SET(upnp_ignore_nonrouters); - CMP_SET(coalesce_writes); - CMP_SET(auto_scrape_interval); - CMP_SET(close_redundant_connections); - CMP_SET(auto_scrape_interval); - CMP_SET(auto_scrape_min_interval); - CMP_SET(max_peerlist_size); - CMP_SET(max_paused_peerlist_size); - CMP_SET(min_announce_interval); - CMP_SET(prioritize_partial_pieces); - CMP_SET(auto_manage_startup); - CMP_SET(rate_limit_ip_overhead); - CMP_SET(announce_to_all_trackers); - CMP_SET(announce_to_all_tiers); - CMP_SET(prefer_udp_trackers); - CMP_SET(strict_super_seeding); - CMP_SET(seeding_piece_quota); - p2 = s->abort(); - delete s; - } - // test snprintf char msg[10]; snprintf(msg, sizeof(msg), "too %s format string", "long"); TEST_CHECK(strcmp(msg, "too long ") == 0); - // test sanitize_path - -#ifdef TORRENT_WINDOWS - TEST_EQUAL(sanitize_path("/a/b/c"), "a\\b\\c"); - TEST_EQUAL(sanitize_path("a/../c"), "a\\c"); -#else - TEST_EQUAL(sanitize_path("/a/b/c"), "a/b/c"); - TEST_EQUAL(sanitize_path("a/../c"), "a/c"); -#endif - TEST_EQUAL(sanitize_path("/.././c"), "c"); - TEST_EQUAL(sanitize_path("dev:"), ""); - TEST_EQUAL(sanitize_path("c:/b"), "b"); -#ifdef TORRENT_WINDOWS - TEST_EQUAL(sanitize_path("c:\\.\\c"), "c"); - TEST_EQUAL(sanitize_path("\\c"), "c"); -#else - TEST_EQUAL(sanitize_path("//./c"), "c"); -#endif - // make sure the time classes have correct semantics TEST_EQUAL(total_milliseconds(milliseconds(100)), 100); @@ -590,110 +245,6 @@ int test_main() TEST_CHECK(identify_client(peer_id("S123--..............")) == "Shadow 1.2.3"); TEST_CHECK(identify_client(peer_id("M1-2-3--............")) == "Mainline 1.2.3"); - // verify_encoding - std::string test = "\b?filename=4"; - TEST_CHECK(!verify_encoding(test)); -#ifdef TORRENT_WINDOWS - TEST_CHECK(test == "__filename=4"); -#else - TEST_CHECK(test == "_?filename=4"); -#endif - - test = "filename=4"; - TEST_CHECK(verify_encoding(test)); - TEST_CHECK(test == "filename=4"); - - // valid 2-byte sequence - test = "filename\xc2\xa1"; - TEST_CHECK(verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename\xc2\xa1"); - - // truncated 2-byte sequence - test = "filename\xc2"; - TEST_CHECK(!verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename_"); - - // valid 3-byte sequence - test = "filename\xe2\x9f\xb9"; - TEST_CHECK(verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename\xe2\x9f\xb9"); - - // truncated 3-byte sequence - test = "filename\xe2\x9f"; - TEST_CHECK(!verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename_"); - - // truncated 3-byte sequence - test = "filename\xe2"; - TEST_CHECK(!verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename_"); - - // valid 4-byte sequence - test = "filename\xf0\x9f\x92\x88"; - TEST_CHECK(verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename\xf0\x9f\x92\x88"); - - // truncated 4-byte sequence - test = "filename\xf0\x9f\x92"; - TEST_CHECK(!verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename_"); - - // 5-byte utf-8 sequence (not allowed) - test = "filename\xf8\x9f\x9f\x9f\x9f""foobar"; - TEST_CHECK(!verify_encoding(test)); - fprintf(stderr, "%s\n", test.c_str()); - TEST_CHECK(test == "filename_____foobar"); - - // trim_path_element - - fprintf(stderr, "TORRENT_MAX_PATH: %d\n", TORRENT_MAX_PATH); - - // 1100 characters - test = "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij012345.txt"; - std::string comparison = test; - trim_path_element(test); - 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 - test = "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" - "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij.123456789abcdefghij0123456789"; - comparison = test; - trim_path_element(test); - if (comparison.size() > TORRENT_MAX_PATH) - comparison.resize(TORRENT_MAX_PATH); - TEST_EQUAL(test, comparison); - // test network functions TEST_CHECK(is_local(address::from_string("192.168.0.1", ec))); @@ -720,51 +271,6 @@ int test_main() address::from_string("10.1.3.3", ec), address::from_string("255.255.0.0", ec))); - // test torrent parsing - - entry info; - info["pieces"] = "aaaaaaaaaaaaaaaaaaaa"; - info["name.utf-8"] = "test1"; - info["name"] = "test__"; - info["piece length"] = 16 * 1024; - info["length"] = 3245; - entry torrent; - torrent["info"] = info; - - std::vector buf; - bencode(std::back_inserter(buf), torrent); - torrent_info ti(&buf[0], buf.size(), ec); - std::cerr << ti.name() << std::endl; - TEST_CHECK(ti.name() == "test1"); - -#ifdef TORRENT_WINDOWS - info["name.utf-8"] = "c:/test1/test2/test3"; -#else - info["name.utf-8"] = "/test1/test2/test3"; -#endif - torrent["info"] = info; - buf.clear(); - bencode(std::back_inserter(buf), torrent); - torrent_info ti2(&buf[0], buf.size(), ec); - std::cerr << ti2.name() << std::endl; -#ifdef TORRENT_WINDOWS - TEST_CHECK(ti2.name() == "test1\\test2\\test3"); -#else - TEST_CHECK(ti2.name() == "test1/test2/test3"); -#endif - - info["name.utf-8"] = "test2/../test3/.././../../test4"; - torrent["info"] = info; - buf.clear(); - bencode(std::back_inserter(buf), torrent); - torrent_info ti3(&buf[0], buf.size(), ec); - std::cerr << ti3.name() << std::endl; -#ifdef TORRENT_WINDOWS - TEST_CHECK(ti3.name() == "test2\\test3\\test4"); -#else - TEST_CHECK(ti3.name() == "test2/test3/test4"); -#endif - // test peer_id/sha1_hash type sha1_hash h1(0); @@ -898,125 +404,6 @@ int test_main() test1.resize(100, true); TEST_CHECK(test1.all_set() == true); - // test merkle_*() functions - - // this is the structure: - // 0 - // 1 2 - // 3 4 5 6 - // 7 8 9 10 11 12 13 14 - // num_leafs = 8 - - TEST_EQUAL(merkle_num_leafs(1), 1); - TEST_EQUAL(merkle_num_leafs(2), 2); - TEST_EQUAL(merkle_num_leafs(3), 4); - TEST_EQUAL(merkle_num_leafs(4), 4); - TEST_EQUAL(merkle_num_leafs(5), 8); - TEST_EQUAL(merkle_num_leafs(6), 8); - TEST_EQUAL(merkle_num_leafs(7), 8); - TEST_EQUAL(merkle_num_leafs(8), 8); - TEST_EQUAL(merkle_num_leafs(9), 16); - TEST_EQUAL(merkle_num_leafs(10), 16); - TEST_EQUAL(merkle_num_leafs(11), 16); - TEST_EQUAL(merkle_num_leafs(12), 16); - TEST_EQUAL(merkle_num_leafs(13), 16); - TEST_EQUAL(merkle_num_leafs(14), 16); - TEST_EQUAL(merkle_num_leafs(15), 16); - TEST_EQUAL(merkle_num_leafs(16), 16); - TEST_EQUAL(merkle_num_leafs(17), 32); - TEST_EQUAL(merkle_num_leafs(18), 32); - - // parents - TEST_EQUAL(merkle_get_parent(1), 0); - TEST_EQUAL(merkle_get_parent(2), 0); - TEST_EQUAL(merkle_get_parent(3), 1); - TEST_EQUAL(merkle_get_parent(4), 1); - TEST_EQUAL(merkle_get_parent(5), 2); - TEST_EQUAL(merkle_get_parent(6), 2); - TEST_EQUAL(merkle_get_parent(7), 3); - TEST_EQUAL(merkle_get_parent(8), 3); - TEST_EQUAL(merkle_get_parent(9), 4); - TEST_EQUAL(merkle_get_parent(10), 4); - TEST_EQUAL(merkle_get_parent(11), 5); - TEST_EQUAL(merkle_get_parent(12), 5); - TEST_EQUAL(merkle_get_parent(13), 6); - TEST_EQUAL(merkle_get_parent(14), 6); - - // siblings - TEST_EQUAL(merkle_get_sibling(1), 2); - TEST_EQUAL(merkle_get_sibling(2), 1); - TEST_EQUAL(merkle_get_sibling(3), 4); - TEST_EQUAL(merkle_get_sibling(4), 3); - TEST_EQUAL(merkle_get_sibling(5), 6); - TEST_EQUAL(merkle_get_sibling(6), 5); - TEST_EQUAL(merkle_get_sibling(7), 8); - TEST_EQUAL(merkle_get_sibling(8), 7); - TEST_EQUAL(merkle_get_sibling(9), 10); - TEST_EQUAL(merkle_get_sibling(10), 9); - TEST_EQUAL(merkle_get_sibling(11), 12); - TEST_EQUAL(merkle_get_sibling(12), 11); - TEST_EQUAL(merkle_get_sibling(13), 14); - TEST_EQUAL(merkle_get_sibling(14), 13); - - // total number of nodes given the number of leafs - TEST_EQUAL(merkle_num_nodes(1), 1); - TEST_EQUAL(merkle_num_nodes(2), 3); - TEST_EQUAL(merkle_num_nodes(4), 7); - TEST_EQUAL(merkle_num_nodes(8), 15); - TEST_EQUAL(merkle_num_nodes(16), 31); - - // 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 buf; - bencode(std::back_inserter(buf), torrent); - printf("%s\n", &buf[0]); - 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())); - } return 0; } diff --git a/test/test_torrent_parse.cpp b/test/test_torrent_parse.cpp index 7f16615e5..cfc542700 100644 --- a/test/test_torrent_parse.cpp +++ b/test/test_torrent_parse.cpp @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "test.hpp" #include "libtorrent/file.hpp" #include "libtorrent/torrent_info.hpp" +#include "libtorrent/bencode.hpp" #if TORRENT_USE_IOSTREAM #include @@ -99,6 +100,13 @@ test_failing_torrent_t test_error_torrents[] = { "invalid_file_size.torrent", errors::torrent_file_parse_failed }, }; +namespace libtorrent +{ + // defined in torrent_info.cpp + TORRENT_EXPORT bool verify_encoding(std::string& target, bool path = true); + TORRENT_EXPORT std::string sanitize_path(std::string const& p); +} + // TODO: test remap_files // TODO: merkle torrents. specifically torrent_info::add_merkle_nodes and torrent with "root hash" // TODO: torrent with 'p' (padfile) attribute @@ -110,10 +118,246 @@ test_failing_torrent_t test_error_torrents[] = int test_main() { + error_code ec; + + // test merkle_*() functions + + // this is the structure: + // 0 + // 1 2 + // 3 4 5 6 + // 7 8 9 10 11 12 13 14 + // num_leafs = 8 + + TEST_EQUAL(merkle_num_leafs(1), 1); + TEST_EQUAL(merkle_num_leafs(2), 2); + TEST_EQUAL(merkle_num_leafs(3), 4); + TEST_EQUAL(merkle_num_leafs(4), 4); + TEST_EQUAL(merkle_num_leafs(5), 8); + TEST_EQUAL(merkle_num_leafs(6), 8); + TEST_EQUAL(merkle_num_leafs(7), 8); + TEST_EQUAL(merkle_num_leafs(8), 8); + TEST_EQUAL(merkle_num_leafs(9), 16); + TEST_EQUAL(merkle_num_leafs(10), 16); + TEST_EQUAL(merkle_num_leafs(11), 16); + TEST_EQUAL(merkle_num_leafs(12), 16); + TEST_EQUAL(merkle_num_leafs(13), 16); + TEST_EQUAL(merkle_num_leafs(14), 16); + TEST_EQUAL(merkle_num_leafs(15), 16); + TEST_EQUAL(merkle_num_leafs(16), 16); + TEST_EQUAL(merkle_num_leafs(17), 32); + TEST_EQUAL(merkle_num_leafs(18), 32); + + // parents + TEST_EQUAL(merkle_get_parent(1), 0); + TEST_EQUAL(merkle_get_parent(2), 0); + TEST_EQUAL(merkle_get_parent(3), 1); + TEST_EQUAL(merkle_get_parent(4), 1); + TEST_EQUAL(merkle_get_parent(5), 2); + TEST_EQUAL(merkle_get_parent(6), 2); + TEST_EQUAL(merkle_get_parent(7), 3); + TEST_EQUAL(merkle_get_parent(8), 3); + TEST_EQUAL(merkle_get_parent(9), 4); + TEST_EQUAL(merkle_get_parent(10), 4); + TEST_EQUAL(merkle_get_parent(11), 5); + TEST_EQUAL(merkle_get_parent(12), 5); + TEST_EQUAL(merkle_get_parent(13), 6); + TEST_EQUAL(merkle_get_parent(14), 6); + + // siblings + TEST_EQUAL(merkle_get_sibling(1), 2); + TEST_EQUAL(merkle_get_sibling(2), 1); + TEST_EQUAL(merkle_get_sibling(3), 4); + TEST_EQUAL(merkle_get_sibling(4), 3); + TEST_EQUAL(merkle_get_sibling(5), 6); + TEST_EQUAL(merkle_get_sibling(6), 5); + TEST_EQUAL(merkle_get_sibling(7), 8); + TEST_EQUAL(merkle_get_sibling(8), 7); + TEST_EQUAL(merkle_get_sibling(9), 10); + TEST_EQUAL(merkle_get_sibling(10), 9); + TEST_EQUAL(merkle_get_sibling(11), 12); + TEST_EQUAL(merkle_get_sibling(12), 11); + TEST_EQUAL(merkle_get_sibling(13), 14); + TEST_EQUAL(merkle_get_sibling(14), 13); + + // total number of nodes given the number of leafs + TEST_EQUAL(merkle_num_nodes(1), 1); + TEST_EQUAL(merkle_num_nodes(2), 3); + TEST_EQUAL(merkle_num_nodes(4), 7); + TEST_EQUAL(merkle_num_nodes(8), 15); + TEST_EQUAL(merkle_num_nodes(16), 31); + + // test sanitize_path + +#ifdef TORRENT_WINDOWS + TEST_EQUAL(sanitize_path("/a/b/c"), "a\\b\\c"); + TEST_EQUAL(sanitize_path("a/../c"), "a\\c"); +#else + TEST_EQUAL(sanitize_path("/a/b/c"), "a/b/c"); + TEST_EQUAL(sanitize_path("a/../c"), "a/c"); +#endif + TEST_EQUAL(sanitize_path("/.././c"), "c"); + TEST_EQUAL(sanitize_path("dev:"), ""); + TEST_EQUAL(sanitize_path("c:/b"), "b"); +#ifdef TORRENT_WINDOWS + TEST_EQUAL(sanitize_path("c:\\.\\c"), "c"); + TEST_EQUAL(sanitize_path("\\c"), "c"); +#else + TEST_EQUAL(sanitize_path("//./c"), "c"); +#endif + + // test torrent parsing + + entry info; + info["pieces"] = "aaaaaaaaaaaaaaaaaaaa"; + info["name.utf-8"] = "test1"; + info["name"] = "test__"; + info["piece length"] = 16 * 1024; + info["length"] = 3245; + entry torrent; + torrent["info"] = info; + + std::vector buf; + bencode(std::back_inserter(buf), torrent); + torrent_info ti(&buf[0], buf.size(), ec); + std::cerr << ti.name() << std::endl; + TEST_CHECK(ti.name() == "test1"); + +#ifdef TORRENT_WINDOWS + info["name.utf-8"] = "c:/test1/test2/test3"; +#else + info["name.utf-8"] = "/test1/test2/test3"; +#endif + torrent["info"] = info; + buf.clear(); + bencode(std::back_inserter(buf), torrent); + torrent_info ti2(&buf[0], buf.size(), ec); + std::cerr << ti2.name() << std::endl; +#ifdef TORRENT_WINDOWS + TEST_CHECK(ti2.name() == "test1\\test2\\test3"); +#else + TEST_CHECK(ti2.name() == "test1/test2/test3"); +#endif + + info["name.utf-8"] = "test2/../test3/.././../../test4"; + torrent["info"] = info; + buf.clear(); + bencode(std::back_inserter(buf), torrent); + torrent_info ti3(&buf[0], buf.size(), ec); + std::cerr << ti3.name() << std::endl; +#ifdef TORRENT_WINDOWS + TEST_CHECK(ti3.name() == "test2\\test3\\test4"); +#else + TEST_CHECK(ti3.name() == "test2/test3/test4"); +#endif + + // verify_encoding + std::string test = "\b?filename=4"; + TEST_CHECK(!verify_encoding(test)); +#ifdef TORRENT_WINDOWS + TEST_CHECK(test == "__filename=4"); +#else + TEST_CHECK(test == "_?filename=4"); +#endif + + test = "filename=4"; + TEST_CHECK(verify_encoding(test)); + TEST_CHECK(test == "filename=4"); + + // valid 2-byte sequence + test = "filename\xc2\xa1"; + TEST_CHECK(verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename\xc2\xa1"); + + // truncated 2-byte sequence + test = "filename\xc2"; + TEST_CHECK(!verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename_"); + + // valid 3-byte sequence + test = "filename\xe2\x9f\xb9"; + TEST_CHECK(verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename\xe2\x9f\xb9"); + + // truncated 3-byte sequence + test = "filename\xe2\x9f"; + TEST_CHECK(!verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename_"); + + // truncated 3-byte sequence + test = "filename\xe2"; + TEST_CHECK(!verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename_"); + + // valid 4-byte sequence + test = "filename\xf0\x9f\x92\x88"; + TEST_CHECK(verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename\xf0\x9f\x92\x88"); + + // truncated 4-byte sequence + test = "filename\xf0\x9f\x92"; + TEST_CHECK(!verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename_"); + + // 5-byte utf-8 sequence (not allowed) + test = "filename\xf8\x9f\x9f\x9f\x9f""foobar"; + TEST_CHECK(!verify_encoding(test)); + fprintf(stderr, "%s\n", test.c_str()); + TEST_CHECK(test == "filename_____foobar"); + + // trim_path_element + + fprintf(stderr, "TORRENT_MAX_PATH: %d\n", TORRENT_MAX_PATH); + + // 1100 characters + test = "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij012345.txt"; + std::string comparison = test; + trim_path_element(test); + 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 + test = "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789" + "abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij.123456789abcdefghij0123456789"; + comparison = test; + trim_path_element(test); + if (comparison.size() > TORRENT_MAX_PATH) + comparison.resize(TORRENT_MAX_PATH); + TEST_EQUAL(test, comparison); + std::string root_dir = parent_path(current_working_directory()); for (int i = 0; i < sizeof(test_torrents)/sizeof(test_torrents[0]); ++i) { - error_code ec; fprintf(stderr, "loading %s\n", test_torrents[i].file); boost::intrusive_ptr ti(new torrent_info(combine_path(combine_path(root_dir, "test_torrents"), test_torrents[i].file), ec)); TEST_CHECK(!ec);