diff --git a/ChangeLog b/ChangeLog index 41b6b203a..f20286710 100644 --- a/ChangeLog +++ b/ChangeLog @@ -106,6 +106,7 @@ * improved LSD performance and made the interval configurable * improved UDP tracker support by caching connect tokens * fast piece optimization + * fixed error handling with torrents with invalid piece sizes * fixed issue with disk read cache not being cleared when removing torrents release 0.14.9 diff --git a/docs/manual.rst b/docs/manual.rst index 5c0753d77..35d87c8f4 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -6275,7 +6275,8 @@ code symbol description ------ ----------------------------------------- ----------------------------------------------------------------- 81 packet_too_large The packet size exceeded the upper sanity check-limit ------ ----------------------------------------- ----------------------------------------------------------------- -82 reserved +82 torrent_invalid_piece_size The .torrent file has an invalid piece size. It needs to be an + even 16 kiB multiple ------ ----------------------------------------- ----------------------------------------------------------------- 83 http_error The web server responded with an error ------ ----------------------------------------- ----------------------------------------------------------------- diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index 3b39784eb..16a29b2f4 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -139,7 +139,7 @@ namespace libtorrent duplicate_peer_id, torrent_removed, packet_too_large, - reserved82, + torrent_invalid_piece_size, http_error, missing_location, invalid_redirection, diff --git a/src/error_code.cpp b/src/error_code.cpp index 00584ffe4..a066b33d8 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -130,7 +130,7 @@ namespace libtorrent "duplicate peer-id", "torrent removed", "packet too large", - "", + "invalid piece size in torrent file", "HTTP error", "missing location header", "invalid redirection", diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 407e88c62..6f9b11b61 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -474,6 +474,7 @@ namespace libtorrent TORRENT_ASSERT(m_seeds >= 0); const int num_pieces = m_piece_map.size(); + if (num_pieces == 0) return std::make_pair(1, 0); int min_availability = piece_pos::max_peer_count; // find the lowest availability count // count the number of pieces that have that availability diff --git a/src/torrent.cpp b/src/torrent.cpp index b6fe8c252..84985213b 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -814,6 +814,15 @@ namespace libtorrent { set_error(errors::too_many_pieces_in_torrent, ""); pause(); + return; + } + + if (m_torrent_file->piece_length() % block_size() != 0) + { + // TODO: try to adjust the block size + set_error(errors::torrent_invalid_piece_size, ""); + pause(); + return; } // the shared_from_this() will create an intentional @@ -4783,11 +4792,11 @@ namespace libtorrent if (valid_metadata()) { - TORRENT_ASSERT(m_abort || !m_picker || m_picker->num_pieces() == m_torrent_file->num_pieces()); + TORRENT_ASSERT(m_abort || m_error || !m_picker || m_picker->num_pieces() == m_torrent_file->num_pieces()); } else { - TORRENT_ASSERT(m_abort || !m_picker || m_picker->num_pieces() == 0); + TORRENT_ASSERT(m_abort || m_error || !m_picker || m_picker->num_pieces() == 0); } #ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS @@ -4844,7 +4853,7 @@ namespace libtorrent } } - if (valid_metadata()) + if (m_files_checked && valid_metadata()) { TORRENT_ASSERT(block_size() > 0); TORRENT_ASSERT((m_torrent_file->piece_length() & (block_size()-1)) == 0); @@ -5024,6 +5033,8 @@ namespace libtorrent m_ses.m_auto_manage_time_scaler = 2; m_error = error_code(); m_error_file.clear(); + // if the error happened during initialization, try again now + if (!m_storage) init(); if (!checking_files && should_check_files()) queue_torrent_check(); }