diff --git a/Jamfile b/Jamfile index e117049c4..6e68b57d4 100644 --- a/Jamfile +++ b/Jamfile @@ -393,12 +393,13 @@ rule tag ( name : type ? : property-set ) feature ipv6 : on off : composite propagated link-incompatible ; feature.compose off : TORRENT_USE_IPV6=0 ; -feature sanitize : off address bounds undefined thread rtc : composite propagated link-incompatible ; +feature sanitize : off address memory bounds undefined thread rtc : composite propagated link-incompatible ; # sanitize is a clang and GCC feature -feature.compose bounds : -fsanitize=bounds -fsanitize-undefined-trap-on-error -fsanitize=bounds -fsanitize-undefined-trap-on-error ; -feature.compose undefined : -fsanitize=undefined -fsanitize=undefined ; +feature.compose bounds : -fsanitize=bounds -fsanitize-undefined-trap-on-error -fsanitize-undefined-trap-on-error ; +feature.compose undefined : -fsanitize=undefined -fsanitize-undefined-trap-on-error -fsanitize=undefined -fsanitize-undefined-trap-on-error ; feature.compose thread : -fsanitize=thread -fsanitize=thread ; feature.compose address : -fsanitize=address -fsanitize=address ; +feature.compose memory : -fsanitize=memory -fsanitize=memory ; # RTC (runtime check) is an msvc feature feature.compose rtc : /RTCc /RTCsu ; diff --git a/include/libtorrent/assert.hpp b/include/libtorrent/assert.hpp index 8ccabf3b8..da597f3e1 100644 --- a/include/libtorrent/assert.hpp +++ b/include/libtorrent/assert.hpp @@ -101,7 +101,7 @@ extern char const* libtorrent_assert_log; #endif #define TORRENT_ASSERT_FAIL() \ - assert_fail("", __LINE__, __FILE__, TORRENT_FUNCTION, 0, 0) + assert_fail("", __LINE__, __FILE__, TORRENT_FUNCTION, nullptr, 0) #else #include diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index e2090d83e..8926b448f 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -282,7 +282,7 @@ namespace aux { void set_peer_info(torrent_peer* pi) override { - TORRENT_ASSERT(m_peer_info == 0 || pi == 0 ); + TORRENT_ASSERT(m_peer_info == nullptr || pi == nullptr ); TORRENT_ASSERT(pi != nullptr || m_disconnect_started); m_peer_info = pi; } diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index 7bbaeb735..8ea8e486a 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -408,7 +408,7 @@ namespace libtorrent { void check_peer_invariant(typed_bitfield const& have , torrent_peer const* p) const; - void check_invariant(const torrent* t = 0) const; + void check_invariant(const torrent* t = nullptr) const; #endif // functor that compares indices on downloading_pieces diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 6502f7ead..849bebee2 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -75,10 +75,10 @@ namespace libtorrent { #if TORRENT_USE_ASSERTS #define TORRENT_PIECE_ASSERT(cond, piece) \ - do { if (!(cond)) { assert_print_piece(piece); assert_fail(#cond, __LINE__, __FILE__, TORRENT_FUNCTION, 0); } } TORRENT_WHILE_0 + do { if (!(cond)) { assert_print_piece(piece); assert_fail(#cond, __LINE__, __FILE__, TORRENT_FUNCTION, nullptr); } } TORRENT_WHILE_0 #define TORRENT_PIECE_ASSERT_FAIL(piece) \ - do { assert_print_piece(piece); assert_fail("", __LINE__, __FILE__, TORRENT_FUNCTION, 0); } TORRENT_WHILE_0 + do { assert_print_piece(piece); assert_fail("", __LINE__, __FILE__, TORRENT_FUNCTION, nullptr); } TORRENT_WHILE_0 #else #define TORRENT_PIECE_ASSERT(cond, piece) do {} TORRENT_WHILE_0 diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 065656c48..9e2cd2a66 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -99,7 +99,7 @@ namespace libtorrent { static const char invalid_chars[] = "/\\"; #endif if (c > 127) return false; - return std::strchr(invalid_chars, static_cast(c)) != NULL; + return std::strchr(invalid_chars, static_cast(c)) != nullptr; } } // anonymous namespace @@ -1014,6 +1014,15 @@ namespace { return false; } + // we expect the piece hashes to be < 2 GB in size + if (files.num_pieces() >= std::numeric_limits::max() / 20) + { + ec = errors::too_many_pieces_in_torrent; + // mark the torrent as invalid + m_files.set_piece_length(0); + return false; + } + if (pieces) { if (pieces.string_length() != files.num_pieces() * 20) @@ -1038,13 +1047,6 @@ namespace { m_files.set_piece_length(0); return false; } - if (files.num_pieces() >= std::numeric_limits::max() / 2) - { - ec = errors::too_many_pieces_in_torrent; - // mark the torrent as invalid - m_files.set_piece_length(0); - return false; - } int const num_leafs = merkle_num_leafs(files.num_pieces()); int const num_nodes = merkle_num_nodes(num_leafs); m_merkle_first_leaf = num_nodes - num_leafs; diff --git a/test/setup_transfer.hpp b/test/setup_transfer.hpp index c26a091ad..2144cf3df 100644 --- a/test/setup_transfer.hpp +++ b/test/setup_transfer.hpp @@ -76,7 +76,7 @@ EXPORT lt::alert const* wait_for_alert( EXPORT void print_ses_rate(float time , lt::torrent_status const* st1 , lt::torrent_status const* st2 - , lt::torrent_status const* st3 = NULL); + , lt::torrent_status const* st3 = nullptr); EXPORT bool print_alerts(lt::session& ses, char const* name , bool allow_no_torrents = false @@ -96,7 +96,7 @@ EXPORT std::shared_ptr make_torrent(const int file_sizes[] EXPORT void create_random_files(std::string const& path, const int file_sizes[] , int num_files, libtorrent::file_storage* fs = nullptr); -EXPORT std::shared_ptr create_torrent(std::ostream* file = 0 +EXPORT std::shared_ptr create_torrent(std::ostream* file = nullptr , char const* name = "temporary", int piece_size = 16 * 1024, int num_pieces = 13 , bool add_tracker = true, std::string ssl_certificate = ""); @@ -106,9 +106,11 @@ EXPORT std::tuple* torrent = 0, bool super_seeding = false - , lt::add_torrent_params const* p = 0, bool stop_lsd = true, bool use_ssl_ports = false - , std::shared_ptr* torrent2 = 0); + , std::shared_ptr* torrent = nullptr + , bool super_seeding = false + , lt::add_torrent_params const* p = nullptr + , bool stop_lsd = true, bool use_ssl_ports = false + , std::shared_ptr* torrent2 = nullptr); EXPORT int start_web_server(bool ssl = false, bool chunked = false , bool keepalive = true, int min_interval = 30); diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index bbe89dddf..6afbed57e 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -153,6 +153,7 @@ test_failing_torrent_t test_error_torrents[] = { "invalid_root_hash2.torrent", errors::torrent_missing_pieces }, { "invalid_file_size.torrent", errors::torrent_invalid_length }, { "invalid_symlink.torrent", errors::torrent_invalid_name }, + { "many_pieces.torrent", errors::too_many_pieces_in_torrent }, }; // TODO: test remap_files diff --git a/test/test_torrents/many_pieces.torrent b/test/test_torrents/many_pieces.torrent new file mode 100644 index 000000000..c3bcf856e --- /dev/null +++ b/test/test_torrents/many_pieces.torrent @@ -0,0 +1 @@ +d10:created by10:libtorrent13:creation datei1359599503e4:infod6:lengthi1759218597889e4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW›}ÜA4u,·¼‘‡ee