diff --git a/include/libtorrent/aux_/numeric_cast.hpp b/include/libtorrent/aux_/numeric_cast.hpp index 1ab5779e5..60a5a1b70 100644 --- a/include/libtorrent/aux_/numeric_cast.hpp +++ b/include/libtorrent/aux_/numeric_cast.hpp @@ -58,7 +58,9 @@ namespace libtorrent { namespace aux { T clamp(T v, T lo, T hi) { TORRENT_ASSERT(lo <= hi); - return (v < lo) ? lo : (hi < v) ? hi : v; + if (v < lo) return lo; + if (hi < v) return hi; + return v; } }} diff --git a/include/libtorrent/aux_/portmap.hpp b/include/libtorrent/aux_/portmap.hpp index b9442ac55..d1971c8fa 100644 --- a/include/libtorrent/aux_/portmap.hpp +++ b/include/libtorrent/aux_/portmap.hpp @@ -84,7 +84,13 @@ namespace aux { } inline char const* to_string(portmap_action const act) { - return act == portmap_action::none ? "none" : act == portmap_action::add ? "add" : "delete"; + switch (act) + { + case portmap_action::none: return "none"; + case portmap_action::add: return "add"; + case portmap_action::del: return "delete"; + }; + return ""; } }} diff --git a/include/libtorrent/bencode.hpp b/include/libtorrent/bencode.hpp index 919e29b2e..6117a62e0 100644 --- a/include/libtorrent/bencode.hpp +++ b/include/libtorrent/bencode.hpp @@ -234,7 +234,7 @@ namespace detail { case 'i': { ++in; // 'i' - std::string val = read_until(in, end, 'e', err); + std::string const val = read_until(in, end, 'e', err); if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' @@ -249,12 +249,12 @@ namespace detail { err = true; return; } - } break; + } + break; // ---------------------------------------------- // list case 'l': - { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') @@ -283,12 +283,11 @@ namespace detail { #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' - } break; + break; // ---------------------------------------------- // dictionary case 'd': - { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') @@ -325,7 +324,7 @@ namespace detail { #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' - } break; + break; // ---------------------------------------------- // string diff --git a/include/libtorrent/bitfield.hpp b/include/libtorrent/bitfield.hpp index 99584c9fb..1b54d9f2a 100644 --- a/include/libtorrent/bitfield.hpp +++ b/include/libtorrent/bitfield.hpp @@ -220,8 +220,13 @@ namespace libtorrent { }; const_iterator begin() const noexcept { return const_iterator(m_buf ? buf() : nullptr, 0); } - const_iterator end() const noexcept { return const_iterator( - m_buf ? buf() + num_words() - (((size() & 31) == 0) ? 0 : 1) : nullptr, size() & 31); } + const_iterator end() const noexcept + { + if (m_buf) + return const_iterator(buf() + num_words() - (((size() & 31) == 0) ? 0 : 1), size() & 31); + else + return const_iterator(nullptr, size() & 31); + } // set the size of the bitfield to ``bits`` length. If the bitfield is extended, // the new bits are initialized to ``val``. diff --git a/include/libtorrent/kademlia/node.hpp b/include/libtorrent/kademlia/node.hpp index 189879acc..bd41b3454 100644 --- a/include/libtorrent/kademlia/node.hpp +++ b/include/libtorrent/kademlia/node.hpp @@ -211,8 +211,8 @@ public: { return ep.protocol().family() == m_protocol.protocol.family(); } bool native_address(address const& addr) const { - return (addr.is_v4() && m_protocol.protocol == m_protocol.protocol.v4()) - || (addr.is_v6() && m_protocol.protocol == m_protocol.protocol.v6()); + return (addr.is_v4() && m_protocol.protocol == udp::v4()) + || (addr.is_v6() && m_protocol.protocol == udp::v6()); } private: diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index c9fa41c36..293c148eb 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -83,6 +83,10 @@ namespace libtorrent { class TORRENT_EXTRA_EXPORT piece_picker { + // only defined when TORRENT_PICKER_LOG is defined, used for debugging + // unit tests + friend void print_pieces(piece_picker const& p); + public: enum @@ -480,10 +484,6 @@ namespace libtorrent { , typed_bitfield const& have , picker_options_t options) const; - // only defined when TORRENT_PICKER_LOG is defined, used for debugging - // unit tests - void print_pieces() const; - struct piece_pos { piece_pos() {} diff --git a/include/libtorrent/session_status.hpp b/include/libtorrent/session_status.hpp index c862677d7..b26e02fcc 100644 --- a/include/libtorrent/session_status.hpp +++ b/include/libtorrent/session_status.hpp @@ -41,9 +41,9 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert_types.hpp" #endif +#if TORRENT_ABI_VERSION == 1 namespace libtorrent { -#if TORRENT_ABI_VERSION == 1 // holds counters and gauges for the uTP sockets // deprecated in 1.1 in favor of session_stats counters, which is a more // flexible, extensible and performant mechanism for stats. @@ -224,9 +224,8 @@ namespace libtorrent { int num_torrents; int num_paused_torrents; }; -#endif // TORRENT_ABI_VERSION - } +#endif // TORRENT_ABI_VERSION #endif // TORRENT_SESSION_STATUS_HPP_INCLUDED diff --git a/include/libtorrent/stat_cache.hpp b/include/libtorrent/stat_cache.hpp index 1eae61fb6..8afdd68a2 100644 --- a/include/libtorrent/stat_cache.hpp +++ b/include/libtorrent/stat_cache.hpp @@ -84,7 +84,7 @@ namespace libtorrent { struct stat_cache_t { - stat_cache_t(std::int64_t s): file_size(s) {} // NOLINT + explicit stat_cache_t(std::int64_t s): file_size(s) {} // the size of the file. Negative values have special meaning. -1 means // not-in-cache (i.e. there's no data for this file in the cache). diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 7453b4a96..57c577c96 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -822,13 +822,10 @@ namespace libtorrent { int num_have() const { // pretend we have every piece when in seed mode - if (m_seed_mode) { - return m_torrent_file->num_pieces(); - } - - return has_picker() - ? m_picker->have().num_pieces - : m_have_all ? m_torrent_file->num_pieces() : 0; + if (m_seed_mode) return m_torrent_file->num_pieces(); + if (has_picker()) return m_picker->have().num_pieces; + if (m_have_all) return m_torrent_file->num_pieces(); + return 0; } // the number of pieces that have passed @@ -836,9 +833,9 @@ namespace libtorrent { // flushed to disk yet int num_passed() const { - return has_picker() - ? m_picker->num_passed() - : m_have_all ? m_torrent_file->num_pieces() : 0; + if (has_picker()) return m_picker->num_passed(); + if (m_have_all) return m_torrent_file->num_pieces(); + return 0; } // when we get a have message, this is called for that piece diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 7e17f86fd..11d0da7ba 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -106,7 +106,8 @@ namespace aux { { address_v4::bytes_type v4; address_v6::bytes_type v6; - } addr; + }; + addr_t addr; std::uint16_t port; public: diff --git a/include/libtorrent/union_endpoint.hpp b/include/libtorrent/union_endpoint.hpp index a0f4cbba4..a489a8cc3 100644 --- a/include/libtorrent/union_endpoint.hpp +++ b/include/libtorrent/union_endpoint.hpp @@ -76,7 +76,8 @@ namespace libtorrent { { address_v4::bytes_type v4; address_v6::bytes_type v6; - } addr; + }; + addr_t addr; bool v4:1; }; diff --git a/src/ConvertUTF.cpp b/src/ConvertUTF.cpp index 9137048a4..92b91aaf7 100644 --- a/src/ConvertUTF.cpp +++ b/src/ConvertUTF.cpp @@ -150,7 +150,8 @@ ConversionResult ConvertUTF16toUTF32 ( } if (target >= targetEnd) { source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; + result = targetExhausted; + break; } *target++ = ch; } @@ -267,7 +268,8 @@ ConversionResult ConvertUTF16toUTF8 ( target += bytesToWrite; if (target > targetEnd) { source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; + target -= bytesToWrite; result = targetExhausted; + break; } switch (bytesToWrite) { /* note: everything falls through. */ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; @@ -307,11 +309,16 @@ Boolean isLegalUTF8(const UTF8 *source, int length) { switch (*source) { /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: break; + case 0xE0: if (a < 0xA0) return false; + break; + case 0xED: if (a > 0x9F) return false; + break; + case 0xF0: if (a < 0x90) return false; + break; + case 0xF4: if (a > 0x8F) return false; + break; + default: + break; } case 1: if (*source >= 0x80 && *source < 0xC2) return false; diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 2bae00a7b..9312b44b9 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -943,7 +943,7 @@ namespace { // if we don't have the metadata, we cannot // verify the bitfield size if (t->valid_metadata() - && m_recv_buffer.packet_size() - 1 != (t->torrent_file().num_pieces() + 7) / 8) + && m_recv_buffer.packet_size() - 1 != (t->torrent_file().num_pieces() + CHAR_BIT - 1) / CHAR_BIT) { disconnect(errors::invalid_bitfield_size, operation_t::bittorrent, 2); return; @@ -955,7 +955,7 @@ namespace { typed_bitfield bits; bits.assign(recv_buffer.begin() + 1 - , t->valid_metadata()?get_bitfield().size():(m_recv_buffer.packet_size()-1)*8); + , t->valid_metadata()?get_bitfield().size():(m_recv_buffer.packet_size()-1)*CHAR_BIT); incoming_bitfield(bits); } @@ -1991,7 +1991,9 @@ namespace { const int num_pieces = t->torrent_file().num_pieces(); TORRENT_ASSERT(num_pieces > 0); - const int packet_size = (num_pieces + 7) / 8 + 5; + constexpr std::uint8_t char_bit_mask = CHAR_BIT - 1; + + const int packet_size = (num_pieces + char_bit_mask) / CHAR_BIT + 5; TORRENT_ALLOCA(msg, char, packet_size); if (msg.data() == nullptr) return; // out of memory @@ -2005,7 +2007,7 @@ namespace { std::fill_n(ptr, packet_size - 5, std::uint8_t{0xff}); // Clear trailing bits - msg.back() = static_cast((0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff); + msg.back() = static_cast((0xff << ((CHAR_BIT - (num_pieces & char_bit_mask)) & char_bit_mask)) & 0xff); } else { @@ -2027,7 +2029,7 @@ namespace { // add predictive pieces to the bitfield as well, since we won't // announce them again for (piece_index_t const p : t->predictive_pieces()) - msg[5 + static_cast(p) / 8] |= (0x80 >> (static_cast(p) & 7)); + msg[5 + static_cast(p) / CHAR_BIT] |= (0x80 >> (static_cast(p) & char_bit_mask)); #ifndef TORRENT_DISABLE_LOGGING if (should_log(peer_log_alert::outgoing_message)) @@ -2037,7 +2039,7 @@ namespace { bitfield_string.resize(n_pieces); for (std::size_t k = 0; k < n_pieces; ++k) { - if (msg[5 + int(k) / 8] & (0x80 >> (k % 8))) bitfield_string[k] = '1'; + if (msg[5 + int(k) / CHAR_BIT] & (0x80 >> (k % CHAR_BIT))) bitfield_string[k] = '1'; else bitfield_string[k] = '0'; } peer_log(peer_log_alert::outgoing_message, "BITFIELD" diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index c039372da..db17cabd2 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -71,6 +71,9 @@ namespace libtorrent { namespace dht { namespace { +// the write tokens we generate are 4 bytes +constexpr int write_token_size = 4; + void nop() {} node_id calculate_node_id(node_id const& nid, aux::listen_socket_handle const& sock) @@ -157,7 +160,7 @@ void node::update_node_id() bool node::verify_token(string_view token, sha1_hash const& info_hash , udp::endpoint const& addr) const { - if (token.length() != 4) + if (token.length() != write_token_size) { #ifndef TORRENT_DISABLE_LOGGING if (m_observer != nullptr) @@ -193,7 +196,7 @@ std::string node::generate_token(udp::endpoint const& addr , sha1_hash const& info_hash) { std::string token; - token.resize(4); + token.resize(write_token_size); hasher h; error_code ec; std::string const address = addr.address().to_string(ec); @@ -203,7 +206,7 @@ std::string node::generate_token(udp::endpoint const& addr h.update(info_hash); sha1_hash const hash = h.final(); - std::copy(hash.begin(), hash.begin() + 4, token.begin()); + std::copy(hash.begin(), hash.begin() + write_token_size, token.begin()); TORRENT_ASSERT(std::equal(token.begin(), token.end(), hash.data())); return token; } @@ -278,21 +281,19 @@ void node::incoming(aux::listen_socket_handle const& s, msg const& m) ext_ip = r.dict_find_string("ip"); } - if (ext_ip && ext_ip.string_length() >= 16) + if (ext_ip && ext_ip.string_length() >= int(detail::address_size(udp::v6()))) { // this node claims we use the wrong node-ID! - address_v6::bytes_type b{}; - std::memcpy(&b[0], ext_ip.string_ptr(), 16); + char const* ptr = ext_ip.string_ptr(); if (m_observer != nullptr) - m_observer->set_external_address(m_sock, address_v6(b) + m_observer->set_external_address(m_sock, detail::read_v6_address(ptr) , m.addr.address()); } - else if (ext_ip && ext_ip.string_length() >= 4) + else if (ext_ip && ext_ip.string_length() >= int(detail::address_size(udp::v4()))) { - address_v4::bytes_type b{}; - std::memcpy(&b[0], ext_ip.string_ptr(), 4); + char const* ptr = ext_ip.string_ptr(); if (m_observer != nullptr) - m_observer->set_external_address(m_sock, address_v4(b) + m_observer->set_external_address(m_sock, detail::read_v4_address(ptr) , m.addr.address()); } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index e13e6aaa1..61ef2a949 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -4301,11 +4301,9 @@ namespace libtorrent { std::shared_ptr t = m_torrent.lock(); - if (ec == errors::self_connection) - { - // don't try to connect to ourself again - if (m_peer_info && t) t->ban_peer(m_peer_info); - } + // don't try to connect to ourself again + if (ec == errors::self_connection && m_peer_info && t) + t->ban_peer(m_peer_info); if (m_connecting) { diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index d9ba497ca..8647516ea 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -60,6 +60,47 @@ POSSIBILITY OF SUCH DAMAGE. using namespace std::placeholders; +#if defined TORRENT_PICKER_LOG +#include + +namespace libtorrent { + void print_pieces(piece_picker const& p) + { + int limit = 20; + std::cerr << "[" << &p << "] "; + if (p.m_dirty) + { + std::cerr << " === dirty ===" << std::endl; + return; + } + + for (prio_index_t b : p.m_priority_boundaries) + std::cerr << b << " "; + + std::cerr << std::endl; + prio_index_t index(0); + std::cerr << "[" << &p << "] "; + auto j = p.m_priority_boundaries.begin(); + for (auto i = p.m_pieces.begin(), end(p.m_pieces.end()); i != end; ++i, ++index) + { + if (limit == 0) + { + std::cerr << " ..."; + break; + } + if (*i == -1) break; + while (j != p.m_priority_boundaries.end() && *j <= index) + { + std::cerr << "| "; + ++j; + } + std::cerr << *i << "(" << p.m_piece_map[*i].index << ") "; + --limit; + } + std::cerr << std::endl; + } +} +#endif // TORRENT_PICKER_LOG namespace libtorrent { // TODO: find a better place for this @@ -388,44 +429,6 @@ namespace libtorrent { TORRENT_ASSERT(p == prio); } } - -#if defined TORRENT_PICKER_LOG - void piece_picker::print_pieces() const - { - int limit = 20; - std::cerr << "[" << this << "] "; - if (m_dirty) - { - std::cerr << " === dirty ===" << std::endl; - return; - } - - for (prio_index_t b : m_priority_boundaries) - std::cerr << b << " "; - - std::cerr << std::endl; - prio_index_t index(0); - std::cerr << "[" << this << "] "; - auto j = m_priority_boundaries.begin(); - for (auto i = m_pieces.begin(), end(m_pieces.end()); i != end; ++i, ++index) - { - if (limit == 0) - { - std::cerr << " ..."; - break; - } - if (*i == -1) break; - while (j != m_priority_boundaries.end() && *j <= index) - { - std::cerr << "| "; - ++j; - } - std::cerr << *i << "(" << m_piece_map[*i].index << ") "; - --limit; - } - std::cerr << std::endl; - } -#endif // TORRENT_PICKER_LOG #endif // TORRENT_USE_INVARIANT_CHECKS #if TORRENT_USE_INVARIANT_CHECKS @@ -840,7 +843,7 @@ namespace libtorrent { << " peer_count: " << p.peer_count << " prio: " << p.piece_priority << " index: " << p.index << std::endl; - print_pieces(); + print_pieces(*this); #endif m_pieces.push_back(piece_index_t(-1)); @@ -861,7 +864,7 @@ namespace libtorrent { } while (temp == new_index && priority < int(m_priority_boundaries.size())); new_index = temp; #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); std::cerr << "[" << this << "] " << " index: " << index << " prio: " << priority << " new_index: " << new_index @@ -877,7 +880,7 @@ namespace libtorrent { m_piece_map[index].index = new_index; #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif } } @@ -895,7 +898,7 @@ namespace libtorrent { for (;;) { #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif TORRENT_ASSERT(elem_index < m_pieces.end_index()); prio_index_t temp{}; @@ -920,7 +923,7 @@ namespace libtorrent { m_pieces.pop_back(); TORRENT_ASSERT(next_index == m_pieces.end_index()); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif } @@ -967,7 +970,7 @@ namespace libtorrent { for (;;) { #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif TORRENT_ASSERT(priority > 0); --priority; @@ -983,17 +986,17 @@ namespace libtorrent { if (priority == new_priority) break; } #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif m_pieces[elem_index] = index; m_piece_map[index].index = elem_index; TORRENT_ASSERT(elem_index < m_pieces.end_index()); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif shuffle(priority, elem_index); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif TORRENT_ASSERT(m_piece_map[index].priority(this) == priority); } @@ -1004,7 +1007,7 @@ namespace libtorrent { for (;;) { #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif TORRENT_ASSERT(priority >= 0); TORRENT_ASSERT(priority < int(m_priority_boundaries.size())); @@ -1021,17 +1024,17 @@ namespace libtorrent { if (priority == new_priority) break; } #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif m_pieces[elem_index] = index; m_piece_map[index].index = elem_index; TORRENT_ASSERT(elem_index < m_pieces.end_index()); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif shuffle(priority, elem_index); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif TORRENT_ASSERT(m_piece_map[index].priority(this) == priority); } @@ -1501,7 +1504,7 @@ namespace libtorrent { } #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif // m_priority_boundaries just contain counters of @@ -1517,7 +1520,7 @@ namespace libtorrent { m_pieces.resize(new_size, piece_index_t(0)); #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif // set up m_pieces to contain valid piece indices, based on piece @@ -1554,7 +1557,7 @@ namespace libtorrent { m_dirty = false; #ifdef TORRENT_PICKER_LOG - print_pieces(); + print_pieces(*this); #endif } diff --git a/src/stat_cache.cpp b/src/stat_cache.cpp index 394f67e94..88b2a5b12 100644 --- a/src/stat_cache.cpp +++ b/src/stat_cache.cpp @@ -49,7 +49,7 @@ namespace libtorrent { void stat_cache::set_cache_impl(file_index_t const i, std::int64_t const size) { if (i >= m_stat_cache.end_index()) - m_stat_cache.resize(static_cast(i) + 1, not_in_cache); + m_stat_cache.resize(static_cast(i) + 1, stat_cache_t{not_in_cache}); m_stat_cache[i].file_size = size; } @@ -62,7 +62,7 @@ namespace libtorrent { void stat_cache::set_error_impl(file_index_t const i, error_code const& ec) { if (i >= m_stat_cache.end_index()) - m_stat_cache.resize(static_cast(i) + 1, not_in_cache); + m_stat_cache.resize(static_cast(i) + 1, stat_cache_t{not_in_cache}); int const error_index = add_error(ec); m_stat_cache[i].file_size = file_error - error_index; @@ -80,7 +80,8 @@ namespace libtorrent { { std::lock_guard l(m_mutex); TORRENT_ASSERT(i < fs.end_file()); - if (i >= m_stat_cache.end_index()) m_stat_cache.resize(static_cast(i) + 1, not_in_cache); + if (i >= m_stat_cache.end_index()) m_stat_cache.resize(static_cast(i) + 1 + , stat_cache_t{not_in_cache}); std::int64_t sz = m_stat_cache[i].file_size; if (sz < not_in_cache) { @@ -110,7 +111,7 @@ namespace libtorrent { void stat_cache::reserve(int num_files) { std::lock_guard l(m_mutex); - m_stat_cache.resize(num_files, not_in_cache); + m_stat_cache.resize(num_files, stat_cache_t{not_in_cache}); } void stat_cache::clear()