diff --git a/Jamfile b/Jamfile index 05cacb21c..cb0baddd4 100644 --- a/Jamfile +++ b/Jamfile @@ -386,15 +386,45 @@ rule openssl-include-path ( properties * ) return $(result) ; } +path-constant blacklist-file : tools/sanitizer-blacklist.txt ; + +rule sanitizer-options ( properties * ) +{ + local result ; + if on in $(properties) + { + local sanitizers ; + local blacklist ; + + # sanitize is a clang and GCC feature + # TODO: carve out specific sanitizers based on compiler version + # + if clang in $(properties) + { + sanitizers += address,undefined,implicit-conversion ; + blacklist = -fsanitize-blacklist=$(blacklist-file) ; + } + else if gcc in $(properties) + { + sanitizers = address,undefined,leak ; + } + else if darwin in $(properties) + { + sanitizers = address,undefined ; + } + + local flags = -fsanitize=$(sanitizers) -fno-sanitize-recover=all ; + + result = $(flags) $(flags) $(blacklist) ; + } + return $(result) ; +} + feature openssl-lib : : free path ; feature openssl-include : : free path ; -feature sanitize : off address memory undefined thread rtc : composite propagated link-incompatible ; -# sanitize is a clang and GCC feature -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 ; +feature sanitize : off rtc on : composite propagated link-incompatible ; + # RTC (runtime check) is an msvc feature feature.compose rtc : /RTCc /RTCsu ; @@ -739,6 +769,7 @@ local usage-requirements = # make sure asio uses std::chrono BOOST_ASIO_HAS_STD_CHRONO @linking + @sanitizer-options # msvc optimizations msvc,release:"/OPT:ICF=5" msvc,release:"/OPT:REF" diff --git a/include/libtorrent/flags.hpp b/include/libtorrent/flags.hpp index 8c5811808..455ea5277 100644 --- a/include/libtorrent/flags.hpp +++ b/include/libtorrent/flags.hpp @@ -73,7 +73,7 @@ struct bitfield_flag static constexpr bitfield_flag all() { - return bitfield_flag(~UnderlyingType{0}); + return bitfield_flag(static_cast(~UnderlyingType{0})); } bool constexpr operator==(bitfield_flag const f) const noexcept @@ -117,7 +117,10 @@ struct bitfield_flag constexpr bitfield_flag operator~() const noexcept { - return bitfield_flag(~m_val); + // technically, m_val is promoted to int before applying operator~, which + // means the result may not fit into the underlying type again. So, + // explicitly cast it + return bitfield_flag(static_cast(~m_val)); } bitfield_flag& operator=(bitfield_flag const& rhs) noexcept = default; diff --git a/simulation/test_http_connection.cpp b/simulation/test_http_connection.cpp index 6b8f31f98..c268c9402 100644 --- a/simulation/test_http_connection.cpp +++ b/simulation/test_http_connection.cpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/http_connection.hpp" #include "libtorrent/resolver.hpp" #include "libtorrent/io.hpp" +#include "libtorrent/random.hpp" #include "make_proxy_settings.hpp" @@ -309,7 +310,7 @@ void run_test(lt::aux::proxy_settings ps, std::string url, int expect_size, int sim::http_proxy http_p(proxy_ios, 4445); char data_buffer[4000]; - std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); + lt::aux::random_bytes(data_buffer); std::vector counters(num_counters, 0); @@ -477,7 +478,7 @@ TORRENT_TEST(http_connection_timeout_server_stalls) http_ipv6.register_stall_handler("/timeout"); char data_buffer[4000]; - std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); + lt::aux::random_bytes(data_buffer); int connect_counter = 0; int handler_counter = 0; @@ -534,7 +535,7 @@ TORRENT_TEST(http_connection_timeout_server_does_not_accept) error_condition timed_out(boost::system::errc::timed_out, boost::system::generic_category()); char data_buffer[4000]; - std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); + lt::aux::random_bytes(data_buffer); auto c = test_request(client_ios, resolver , "http://dual-stack.test-hostname.com:8080/timeout_server_does_not_accept", data_buffer, -1, -1 @@ -563,7 +564,7 @@ void test_proxy_failure(lt::settings_pack::proxy_type_t proxy_type) lt::aux::proxy_settings ps = make_proxy_settings(proxy_type); char data_buffer[4000]; - std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); + lt::aux::random_bytes(data_buffer); http.register_handler("/test_file" , [&data_buffer](std::string method, std::string req diff --git a/test/bittorrent_peer.cpp b/test/bittorrent_peer.cpp index 872895963..dd383acd6 100644 --- a/test/bittorrent_peer.cpp +++ b/test/bittorrent_peer.cpp @@ -84,7 +84,7 @@ void peer_conn::on_connect(error_code const& ec) char* h = static_cast(malloc(sizeof(handshake))); memcpy(h, handshake, sizeof(handshake)); std::memcpy(h + 28, m_ti.info_hash().data(), 20); - std::generate(h + 48, h + 68, &rand); + lt::aux::random_bytes({h + 48, 20}); // for seeds, don't send the interested message boost::asio::async_write(s, boost::asio::buffer(h, (sizeof(handshake) - 1) - (m_mode == peer_mode_t::uploader ? 5 : 0)) diff --git a/test/test_dht.cpp b/test/test_dht.cpp index 16546cd0f..71ece3920 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -2603,7 +2603,7 @@ TORRENT_TEST(traversal_done) // invert the ith most significant byte so that the test nodes are // progressively closer to the target item for (int i = 0; i < num_test_nodes; ++i) - nodes[i].id[i] = ~nodes[i].id[i]; + nodes[i].id[i] = static_cast(~nodes[i].id[i]); // add the first k nodes to the subject's routing table for (int i = 0; i < 8; ++i) @@ -3348,6 +3348,8 @@ struct test_algo : dht::traversal_algorithm : traversal_algorithm(dht_node, target) {} + void done() { this->dht::traversal_algorithm::done(); } + std::vector const& results() const { return m_results; } using traversal_algorithm::num_sorted_results; @@ -3387,6 +3389,7 @@ TORRENT_TEST(unsorted_traversal_results) results = algo->results(); TEST_CHECK(results.size() == eps.size()); TEST_CHECK(eps[5] == results[0]->target_ep()); + algo->done(); } TORRENT_TEST(rpc_invalid_error_msg) diff --git a/test/test_http_connection.cpp b/test/test_http_connection.cpp index 33ba26e31..0009c56d8 100644 --- a/test/test_http_connection.cpp +++ b/test/test_http_connection.cpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/socket_io.hpp" // print_endpoint #include "libtorrent/http_connection.hpp" #include "libtorrent/resolver.hpp" +#include "libtorrent/random.hpp" #include #include @@ -144,8 +145,7 @@ void run_test(std::string const& url, int size, int status, int connected void write_test_file() { - std::srand(unsigned(std::time(nullptr))); - std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); + aux::random_bytes(data_buffer); error_code ec; file test_file("test_file", open_mode::write_only, ec); TEST_CHECK(!ec); diff --git a/test/test_privacy.cpp b/test/test_privacy.cpp index 2a1a75cd1..bdfe98040 100644 --- a/test/test_privacy.cpp +++ b/test/test_privacy.cpp @@ -166,15 +166,20 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, flags_t flags) , [&](lt::alert const* a) { if (auto const* ta = alert_cast(a)) + { + std::printf("accepted tracker: %s\n", ta->tracker_url()); accepted_trackers.push_back(ta->tracker_url()); + } return false; }); std::this_thread::sleep_for(lt::milliseconds(100)); if (num_udp_announces() >= prev_udp_announces + 1 && num_peer_hits() > 0 - && !accepted_trackers.empty()) + && accepted_trackers.size() >= 2) + { break; + } } // we should have announced to the tracker by now diff --git a/tools/sanitizer-blacklist.txt b/tools/sanitizer-blacklist.txt new file mode 100644 index 000000000..968416d52 --- /dev/null +++ b/tools/sanitizer-blacklist.txt @@ -0,0 +1,4 @@ +# this function relies on implicit integer truncation +fun:_ZN5boost6detail10crc_helper*index* +fun:_ZN3std*mersenne_twister_engine* +