From 5ba1f46ae137ba19f3111a5a55b204cc62bf3123 Mon Sep 17 00:00:00 2001 From: xavier2k6 <42386382+xavier2k6@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:53:18 +0000 Subject: [PATCH 1/9] Fix typos --- bindings/python/src/torrent_handle.cpp | 8 ++++---- cmake/Modules/GeneratePkgConfig.cmake | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bindings/python/src/torrent_handle.cpp b/bindings/python/src/torrent_handle.cpp index 41247f29f21..56801c54552 100644 --- a/bindings/python/src/torrent_handle.cpp +++ b/bindings/python/src/torrent_handle.cpp @@ -177,12 +177,12 @@ list file_priorities(torrent_handle& handle) return ret; } -download_priority_t file_prioritity0(torrent_handle& h, file_index_t index) +download_priority_t file_priority0(torrent_handle& h, file_index_t index) { return h.file_priority(index); } -void file_prioritity1(torrent_handle& h, file_index_t index, download_priority_t prio) +void file_priority1(torrent_handle& h, file_index_t index, download_priority_t prio) { return h.file_priority(index, prio); } @@ -532,8 +532,8 @@ void bind_torrent_handle() .def("get_piece_priorities", &piece_priorities) .def("prioritize_files", &prioritize_files) .def("get_file_priorities", &file_priorities) - .def("file_priority", &file_prioritity0) - .def("file_priority", &file_prioritity1) + .def("file_priority", &file_priority0) + .def("file_priority", &file_priority1) .def("file_status", _(file_status0)) .def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags") = 0) .def("need_save_resume_data", _(need_save_resume_data0)) diff --git a/cmake/Modules/GeneratePkgConfig.cmake b/cmake/Modules/GeneratePkgConfig.cmake index fa523496422..49a14a6cb15 100644 --- a/cmake/Modules/GeneratePkgConfig.cmake +++ b/cmake/Modules/GeneratePkgConfig.cmake @@ -9,10 +9,10 @@ set(_GeneratePkGConfigDir "${CMAKE_CURRENT_LIST_DIR}/GeneratePkgConfig") include(GNUInstallDirs) -function(_get_target_property_merging_configs _var_name _target_name _propert_name) - get_property(prop_set TARGET ${_target_name} PROPERTY ${_propert_name} SET) +function(_get_target_property_merging_configs _var_name _target_name _property_name) + get_property(prop_set TARGET ${_target_name} PROPERTY ${_property_name} SET) if (prop_set) - get_property(vals TARGET ${_target_name} PROPERTY ${_propert_name}) + get_property(vals TARGET ${_target_name} PROPERTY ${_property_name}) else() if (CMAKE_BUILD_TYPE) list(APPEND configs ${CMAKE_BUILD_TYPE}) @@ -27,9 +27,9 @@ function(_get_target_property_merging_configs _var_name _target_name _propert_na else() set(target_cfg "${UPPERCFG}") endif() - get_property(prop_set TARGET ${_target_name} PROPERTY ${_propert_name}_${target_cfg} SET) + get_property(prop_set TARGET ${_target_name} PROPERTY ${_property_name}_${target_cfg} SET) if (prop_set) - get_property(val_for_cfg TARGET ${_target_name} PROPERTY ${_propert_name}_${target_cfg}) + get_property(val_for_cfg TARGET ${_target_name} PROPERTY ${_property_name}_${target_cfg}) list(APPEND vals "$<$:${val_for_cfg}>") break() endif() @@ -38,7 +38,7 @@ function(_get_target_property_merging_configs _var_name _target_name _propert_na get_property(imported_cfgs TARGET ${_target_name} PROPERTY IMPORTED_CONFIGURATIONS) # CMake docs say we can use any of the imported configs list(GET imported_cfgs 0 imported_config) - get_property(vals TARGET ${_target_name} PROPERTY ${_propert_name}_${imported_config}) + get_property(vals TARGET ${_target_name} PROPERTY ${_property_name}_${imported_config}) # remove config generator expression. Only in this case! Notice we use such expression # ourselves in the loop above string(REPLACE "$<$:" "$<1:" vals "${vals}") From dc035e8ec85363f213cbfe53528430781e1ebc4c Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 25 Jan 2025 02:50:14 +0100 Subject: [PATCH 2/9] add some possible values to the documentation for dht_bootstrap_nodes --- docs/hunspell/libtorrent.dic | 2 ++ include/libtorrent/settings_pack.hpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/docs/hunspell/libtorrent.dic b/docs/hunspell/libtorrent.dic index d1bcb5a7f17..55231cb9a16 100644 --- a/docs/hunspell/libtorrent.dic +++ b/docs/hunspell/libtorrent.dic @@ -634,3 +634,5 @@ I3 SSD DAX WebDAV +transmissionbt +ouinet diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 8fd5e236038..b35729d6dff 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -385,6 +385,10 @@ namespace aux { // // Changing these after the DHT has been started may not have any // effect until the DHT is restarted. + // Here are some other bootstrap nodes that may work: + // ``router.bittorrent.com:6881``, + // ``dht.transmissionbt.com:6881`` + // ``router.bt.ouinet.work:6881``, dht_bootstrap_nodes, max_string_setting_internal From 7de186fcc6d390f2c7c1d60189d3f82022f32336 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 25 Jan 2025 15:34:23 +0100 Subject: [PATCH 3/9] fix applying IP filter to DHT traffic (HanabishiRecca) --- ChangeLog | 1 + src/torrent.cpp | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index a22974aaacf..1d867fbe165 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2.0.11 released + * fix applying IP filter to DHT traffic (HanabishiRecca) * fix race condition when cancelling requests after becoming a seed * fix performance bug in the file pool, evicting MRU instead of LRU (HanabishiRecca) * fix bug where file_progress could sometimes be reported as >100% diff --git a/src/torrent.cpp b/src/torrent.cpp index 90a5408b3b3..7f731e12393 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -11182,17 +11182,6 @@ namespace { TORRENT_ASSERT(info_hash().has_v2() || !(flags & pex_lt_v2)); -#ifndef TORRENT_DISABLE_DHT - if (source != peer_info::resume_data) - { - // try to send a DHT ping to this peer - // as well, to figure out if it supports - // DHT (uTorrent and BitComet don't - // advertise support) - session().add_dht_node({adr.address(), adr.port()}); - } -#endif - if (m_apply_ip_filter && m_ip_filter && m_ip_filter->access(adr.address()) & ip_filter::blocked) @@ -11241,6 +11230,17 @@ namespace { return nullptr; } +#ifndef TORRENT_DISABLE_DHT + if (source != peer_info::resume_data) + { + // try to send a DHT ping to this peer + // as well, to figure out if it supports + // DHT (uTorrent and BitComet don't + // advertise support) + session().add_dht_node({adr.address(), adr.port()}); + } +#endif + if (!torrent_file().info_hashes().has_v1()) flags |= pex_lt_v2; From 91448ac519857f3795bd6064c28634c7952c1ebe Mon Sep 17 00:00:00 2001 From: xavier2k6 <42386382+xavier2k6@users.noreply.github.com> Date: Mon, 2 Dec 2024 00:26:30 +0000 Subject: [PATCH 4/9] cibuildwheel: update workflow --- .github/workflows/cibuildwheel.yml | 72 ++++++++++++++++++++++-------- tools/cibuildwheel/setup_boost.sh | 2 +- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index 11d56ca5765..876182ca9ca 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -6,7 +6,7 @@ name: cibuildwheel # sample. # The full list of cibuildwheel's build targets can be found here: -# https://github.com/pypa/cibuildwheel/blob/v2.21.3/cibuildwheel/resources/build-platforms.toml +# https://github.com/pypa/cibuildwheel/blob/v2.22.0/cibuildwheel/resources/build-platforms.toml # Notes on build targets we (don't) support: # - pypy: libtorrent doesn't build with pypy as of writing @@ -45,31 +45,65 @@ jobs: MATRIX_PULL_REQUEST: | { "include": [ - {"os": "ubuntu-latest", "CIBW_BUILD": "cp39-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp39-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp39-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp39-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, - {"os": "macos-12", "CIBW_BUILD": "cp39-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "12"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp39-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp39-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp39-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp39-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, {"os": "macos-13", "CIBW_BUILD": "cp39-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, {"os": "macos-14", "CIBW_BUILD": "cp39-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, {"os": "macos-15", "CIBW_BUILD": "cp39-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, - {"os": "windows-latest", "CIBW_BUILD": "cp39-win32", "CIBW_ARCHS_WINDOWS": "x86"}, - {"os": "windows-latest", "CIBW_BUILD": "cp39-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"} + {"os": "windows-2022", "CIBW_BUILD": "cp39-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp39-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"} ] } MATRIX_WORKFLOW_DISPATCH: | { "include": [ - {"os": "ubuntu-latest", "CIBW_BUILD": "cp*-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp*-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp*-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, - {"os": "ubuntu-latest", "CIBW_BUILD": "cp*-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, - {"os": "macos-12", "CIBW_BUILD": "cp*-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "12"}, - {"os": "macos-13", "CIBW_BUILD": "cp*-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, - {"os": "macos-14", "CIBW_BUILD": "cp*-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, - {"os": "macos-15", "CIBW_BUILD": "cp*-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, - {"os": "windows-latest", "CIBW_BUILD": "cp*-win32", "CIBW_ARCHS_WINDOWS": "x86"}, - {"os": "windows-latest", "CIBW_BUILD": "cp*-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"} + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp39-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp310-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp311-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp312-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp313-manylinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp39-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp310-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp311-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp312-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp313-manylinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp39-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp310-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp311-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp312-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04", "CIBW_BUILD": "cp313-musllinux_x86_64", "CIBW_ARCHS_LINUX": "x86_64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp39-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp310-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp311-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp312-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "ubuntu-24.04-arm", "CIBW_BUILD": "cp313-musllinux_aarch64", "CIBW_ARCHS_LINUX": "aarch64"}, + {"os": "macos-13", "CIBW_BUILD": "cp39-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, + {"os": "macos-13", "CIBW_BUILD": "cp310-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, + {"os": "macos-13", "CIBW_BUILD": "cp311-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, + {"os": "macos-13", "CIBW_BUILD": "cp312-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, + {"os": "macos-13", "CIBW_BUILD": "cp313-macosx_x86_64", "CIBW_ARCHS_MACOS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "13"}, + {"os": "macos-14", "CIBW_BUILD": "cp39-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, + {"os": "macos-14", "CIBW_BUILD": "cp310-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, + {"os": "macos-14", "CIBW_BUILD": "cp311-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, + {"os": "macos-14", "CIBW_BUILD": "cp312-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, + {"os": "macos-14", "CIBW_BUILD": "cp313-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "14"}, + {"os": "macos-15", "CIBW_BUILD": "cp39-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, + {"os": "macos-15", "CIBW_BUILD": "cp310-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, + {"os": "macos-15", "CIBW_BUILD": "cp311-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, + {"os": "macos-15", "CIBW_BUILD": "cp312-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, + {"os": "macos-15", "CIBW_BUILD": "cp313-macosx_arm64", "CIBW_ARCHS_MACOS": "arm64", "MACOSX_DEPLOYMENT_TARGET": "15"}, + {"os": "windows-2022", "CIBW_BUILD": "cp39-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp310-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp311-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp312-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp313-win32", "CIBW_ARCHS_WINDOWS": "x86"}, + {"os": "windows-2022", "CIBW_BUILD": "cp39-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"}, + {"os": "windows-2022", "CIBW_BUILD": "cp310-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"}, + {"os": "windows-2022", "CIBW_BUILD": "cp311-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"}, + {"os": "windows-2022", "CIBW_BUILD": "cp312-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"}, + {"os": "windows-2022", "CIBW_BUILD": "cp313-win_amd64", "CIBW_ARCHS_WINDOWS": "AMD64"} ] } @@ -126,7 +160,7 @@ jobs: vcpkg install openssl:x86-windows New-Item -Path "C:\Program Files\OpenSSL" -ItemType SymbolicLink -Value "C:\vcpkg\packages\openssl_x86-windows\" - - uses: pypa/cibuildwheel@v2.21.3 + - uses: pypa/cibuildwheel@v2.22.0 if: steps.cache-wheel.outputs.cache-hit != 'true' - uses: actions/upload-artifact@v4 diff --git a/tools/cibuildwheel/setup_boost.sh b/tools/cibuildwheel/setup_boost.sh index c369d01050b..b215af256fa 100755 --- a/tools/cibuildwheel/setup_boost.sh +++ b/tools/cibuildwheel/setup_boost.sh @@ -14,7 +14,7 @@ TEMP_ARCHIVE="$(mktemp)" mkdir -p "$BOOST_ROOT" -curl -L -o "$TEMP_ARCHIVE" "https://boostorg.jfrog.io/artifactory/main/release/${VERSION}/source/boost_${VUNDER}.tar.gz" +curl -L -o "$TEMP_ARCHIVE" "https://archives.boost.io/release/${VERSION}/source/boost_${VUNDER}.tar.gz" tar -z -x -C "$BOOST_ROOT" -f "$TEMP_ARCHIVE" --strip-components 1 rm "$TEMP_ARCHIVE" From 9bd55cbc3d96d619a827f451a35a56d3923d9e1c Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 9 Nov 2024 13:24:11 +0100 Subject: [PATCH 5/9] add invariant check to socks5_stream and make it resilient to a race when closing the socket --- include/libtorrent/i2p_stream.hpp | 6 ----- include/libtorrent/proxy_base.hpp | 37 +++++++++++++++++++++++++++++-- src/i2p_stream.cpp | 8 ------- src/proxy_base.cpp | 9 +++++++- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/include/libtorrent/i2p_stream.hpp b/include/libtorrent/i2p_stream.hpp index cc6c40a68f3..55d69148031 100644 --- a/include/libtorrent/i2p_stream.hpp +++ b/include/libtorrent/i2p_stream.hpp @@ -113,9 +113,6 @@ struct i2p_stream : proxy_base { explicit i2p_stream(io_context& io_context); i2p_stream(i2p_stream&&) noexcept = default; -#if TORRENT_USE_ASSERTS - ~i2p_stream(); -#endif // explicitly disallow assignment, to silence msvc warning i2p_stream& operator=(i2p_stream const&) = delete; @@ -479,9 +476,6 @@ struct i2p_stream : proxy_base command_t m_command; state_t m_state; -#if TORRENT_USE_ASSERTS - int m_magic = 0x1337; -#endif }; class i2p_connection diff --git a/include/libtorrent/proxy_base.hpp b/include/libtorrent/proxy_base.hpp index e3a1f4d4767..05634744db8 100644 --- a/include/libtorrent/proxy_base.hpp +++ b/include/libtorrent/proxy_base.hpp @@ -61,6 +61,7 @@ struct proxy_base void set_proxy(std::string hostname, int port) { + TORRENT_ASSERT(m_magic == 0x1337); m_hostname = std::move(hostname); m_port = port; } @@ -71,18 +72,21 @@ struct proxy_base template void async_read_some(Mutable_Buffers const& buffers, Handler handler) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.async_read_some(buffers, std::move(handler)); } template std::size_t read_some(Mutable_Buffers const& buffers, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.read_some(buffers, ec); } template std::size_t write_some(Const_Buffers const& buffers, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.write_some(buffers, ec); } @@ -96,18 +100,21 @@ struct proxy_base template std::size_t read_some(Mutable_Buffers const& buffers) { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.read_some(buffers); } template std::size_t write_some(Const_Buffers const& buffers) { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.write_some(buffers); } template void io_control(IO_Control_Command& ioc) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.io_control(ioc); } #endif @@ -115,12 +122,14 @@ struct proxy_base template void io_control(IO_Control_Command& ioc, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.io_control(ioc, ec); } template void async_write_some(Const_Buffers const& buffers, Handler handler) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.async_write_some(buffers, std::move(handler)); } @@ -134,6 +143,7 @@ struct proxy_base template void async_wait(tcp::socket::wait_type type, Handler handler) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.async_wait(type, std::move(handler)); } #endif @@ -141,12 +151,14 @@ struct proxy_base #ifndef BOOST_NO_EXCEPTIONS void non_blocking(bool b) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.non_blocking(b); } #endif void non_blocking(bool b, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.non_blocking(b, ec); } @@ -154,6 +166,7 @@ struct proxy_base template void set_option(SettableSocketOption const& opt) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.set_option(opt); } #endif @@ -161,6 +174,7 @@ struct proxy_base template void set_option(SettableSocketOption const& opt, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.set_option(opt, ec); } @@ -168,6 +182,7 @@ struct proxy_base template void get_option(GettableSocketOption& opt) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.get_option(opt); } #endif @@ -175,28 +190,33 @@ struct proxy_base template void get_option(GettableSocketOption& opt, error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.get_option(opt, ec); } #ifndef BOOST_NO_EXCEPTIONS void bind(endpoint_type const& /* endpoint */) { + TORRENT_ASSERT(m_magic == 0x1337); // m_sock.bind(endpoint); } #endif void cancel() { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.cancel(); } void cancel(error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_sock.cancel(ec); } void bind(endpoint_type const& /* endpoint */, error_code& /* ec */) { + TORRENT_ASSERT(m_magic == 0x1337); // the reason why we ignore binds here is because we don't // (necessarily) yet know what address family the proxy // will resolve to, and binding to the wrong one would @@ -211,12 +231,14 @@ struct proxy_base #ifndef BOOST_NO_EXCEPTIONS void open(protocol_type const&) { + TORRENT_ASSERT(m_magic == 0x1337); // m_sock.open(p); } #endif void open(protocol_type const&, error_code&) { + TORRENT_ASSERT(m_magic == 0x1337); // we need to ignore this for the same reason as stated // for ignoring bind() // m_sock.open(p, ec); @@ -225,6 +247,7 @@ struct proxy_base #ifndef BOOST_NO_EXCEPTIONS void close() { + TORRENT_ASSERT(m_magic == 0x1337); m_remote_endpoint = endpoint_type(); m_sock.close(); m_resolver.cancel(); @@ -233,6 +256,7 @@ struct proxy_base void close(error_code& ec) { + TORRENT_ASSERT(m_magic == 0x1337); m_remote_endpoint = endpoint_type(); m_sock.close(ec); m_resolver.cancel(); @@ -241,12 +265,14 @@ struct proxy_base #ifndef BOOST_NO_EXCEPTIONS endpoint_type remote_endpoint() const { + TORRENT_ASSERT(m_magic == 0x1337); return m_remote_endpoint; } #endif endpoint_type remote_endpoint(error_code& ec) const { + TORRENT_ASSERT(m_magic == 0x1337); if (!m_sock.is_open()) ec = boost::asio::error::not_connected; return m_remote_endpoint; } @@ -254,12 +280,14 @@ struct proxy_base #ifndef BOOST_NO_EXCEPTIONS endpoint_type local_endpoint() const { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.local_endpoint(); } #endif endpoint_type local_endpoint(error_code& ec) const { + TORRENT_ASSERT(m_magic == 0x1337); return m_sock.local_endpoint(ec); } @@ -280,8 +308,9 @@ struct proxy_base // The handler must be taken as lvalue reference here since we may not call // it. But if we do, we want the call operator to own the function object. template - bool handle_error(error_code const& e, Handler&& h) + bool handle_error(error_code e, Handler&& h) { + TORRENT_ASSERT(m_magic == 0x1337); if (!e) return false; std::forward(h)(e); error_code ec; @@ -291,12 +320,16 @@ struct proxy_base aux::noexcept_movable m_sock; std::string m_hostname; // proxy host - int m_port; // proxy port + int m_port = 0; // proxy port aux::noexcept_movable m_remote_endpoint; // TODO: 2 use the resolver interface that has a built-in cache aux::noexcept_move_only m_resolver; + +#if TORRENT_USE_ASSERTS + int m_magic = 0x1337; +#endif }; template diff --git a/src/i2p_stream.cpp b/src/i2p_stream.cpp index acf20f4f24c..27a37824fa2 100644 --- a/src/i2p_stream.cpp +++ b/src/i2p_stream.cpp @@ -121,14 +121,6 @@ namespace libtorrent { , m_state(read_hello_response) {} -#if TORRENT_USE_ASSERTS - i2p_stream::~i2p_stream() - { - TORRENT_ASSERT(m_magic == 0x1337); - m_magic = 0; - } -#endif - static_assert(std::is_nothrow_move_constructible::value , "should be nothrow move constructible"); } diff --git a/src/proxy_base.cpp b/src/proxy_base.cpp index 10c1cd81db8..43bead6b955 100644 --- a/src/proxy_base.cpp +++ b/src/proxy_base.cpp @@ -36,11 +36,18 @@ namespace libtorrent { proxy_base::proxy_base(io_context& io_context) : m_sock(io_context) - , m_port(0) , m_resolver(io_context) {} +#if TORRENT_USE_ASSERTS + proxy_base::~proxy_base() + { + TORRENT_ASSERT(m_magic == 0x1337); + m_magic = 0; + } +#else proxy_base::~proxy_base() = default; +#endif static_assert(std::is_nothrow_move_constructible::value , "should be nothrow move constructible"); From 06a55f77da5f03872dbec028d62567b46151123c Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 25 Jan 2025 10:04:42 +0100 Subject: [PATCH 6/9] fix fcntl.h warninig --- src/drive_info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drive_info.cpp b/src/drive_info.cpp index 766bfa07f1a..579dd781a03 100644 --- a/src/drive_info.cpp +++ b/src/drive_info.cpp @@ -41,8 +41,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include #include // for major()/minor() +#include #include #include From 44f19a6cfc6addaf03b3eab1f06a8f1c5055c6bf Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 25 Jan 2025 13:48:46 +0100 Subject: [PATCH 7/9] use stricter rules for what filenames are valid on Android --- ChangeLog | 1 + src/torrent_info.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1d867fbe165..5b1ea0ef1cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2.0.11 released + * use stricter rules for what filenames are valid on Android * fix applying IP filter to DHT traffic (HanabishiRecca) * fix race condition when cancelling requests after becoming a seed * fix performance bug in the file pool, evicting MRU instead of LRU (HanabishiRecca) diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index df1f7711ed8..933eb14d83e 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -85,10 +85,22 @@ namespace libtorrent { namespace { + // Which characters are valid is primarily determined by the + // filesystem, so this logic is an approximation. Note that forward- and + // backslash are filtered unconditionally and separately from this function. bool valid_path_character(std::int32_t const c) { #ifdef TORRENT_WINDOWS + // On windows, both the filesystem and the operating system impose + // restrictions. static const char invalid_chars[] = "?<>\"|\b*:"; +#elif defined TORRENT_ANDROID + // The Android kernel probably has similar restrictions as Linux (i.e. + // very few) but it appears some user-space system libraries impose + // additional restrictions, and it's probably more common to use FAT32 + // style filesystems, which also further restricts valid characters + // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/FileUtils.java;l=997?q=isValidFatFilenameChar + static const char invalid_chars[] = "\"*:<>?|"; #else static const char invalid_chars[] = ""; #endif From 9d7443f467147d1784fb7516d2a882db1abb5a8b Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 25 Jan 2025 01:24:41 +0100 Subject: [PATCH 8/9] validate add_torrent_params::save_path at run-time --- ChangeLog | 1 + include/libtorrent/error_code.hpp | 2 ++ include/libtorrent/session_handle.hpp | 6 ++++++ src/error_code.cpp | 2 +- src/session_handle.cpp | 21 ++++++++++++++++++++- test/test_session.cpp | 17 +++++++++++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b1ea0ef1cf..c98ab023de6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2.0.11 released + * validate add_torrent_params::save_path at run-time * use stricter rules for what filenames are valid on Android * fix applying IP filter to DHT traffic (HanabishiRecca) * fix race condition when cancelling requests after becoming a seed diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index 34497865040..d34ab0e3887 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -389,6 +389,8 @@ namespace errors { // specifying the flag to only save when there's anything new to save // (torrent_handle::only_if_modified) and there wasn't anything changed. resume_data_not_modified, + // the save_path in add_torrent_params is not valid + invalid_save_path, // The HTTP header was not correctly formatted diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index e90d4c8b462..2dafaf5db65 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -264,6 +264,12 @@ namespace libtorrent { // immediately, without waiting for the torrent to add. Notification of // the torrent being added is sent as add_torrent_alert. // + // The ``save_path`` field in add_torrent_params must be set to a valid + // path where the files for the torrent will be saved. Even when using a + // custom storage, this needs to be set to something. If the save_path + // is empty, the call to add_torrent() will throw a system_error + // exception. + // // The overload that does not take an error_code throws an exception on // error and is not available when building without exception support. // The torrent_handle returned by add_torrent() can be used to retrieve diff --git a/src/error_code.cpp b/src/error_code.cpp index 4775eee5d56..98c49ede4d1 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -206,7 +206,7 @@ namespace libtorrent { "invalid piece index in slot list", "pieces needs to be reordered", "fastresume not modified since last save", - "", + "invalid save_path", "", "", "", diff --git a/src/session_handle.cpp b/src/session_handle.cpp index e4bb290eeb8..0467a9b782e 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -405,7 +405,12 @@ namespace { #ifndef BOOST_NO_EXCEPTIONS torrent_handle session_handle::add_torrent(add_torrent_params&& params) { +#ifndef BOOST_NO_EXCEPTIONS + if (params.save_path.empty()) + aux::throw_ex(error_code(errors::invalid_save_path)); +#else TORRENT_ASSERT_PRECOND(!params.save_path.empty()); +#endif #if TORRENT_ABI_VERSION < 3 if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti) @@ -435,7 +440,11 @@ namespace { torrent_handle session_handle::add_torrent(add_torrent_params&& params, error_code& ec) { - TORRENT_ASSERT_PRECOND(!params.save_path.empty()); + if (params.save_path.empty()) + { + ec = error_code(errors::invalid_save_path); + return {}; + } #if TORRENT_ABI_VERSION < 3 if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti) @@ -467,7 +476,12 @@ namespace { void session_handle::async_add_torrent(add_torrent_params&& params) { +#ifndef BOOST_NO_EXCEPTIONS + if (params.save_path.empty()) + aux::throw_ex(error_code(errors::invalid_save_path)); +#else TORRENT_ASSERT_PRECOND(!params.save_path.empty()); +#endif #if TORRENT_ABI_VERSION < 3 if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti) @@ -528,7 +542,12 @@ namespace { , bool const add_paused , client_data_t userdata) { +#ifndef BOOST_NO_EXCEPTIONS + if (save_path.empty()) + aux::throw_ex(error_code(errors::invalid_save_path)); +#else TORRENT_ASSERT_PRECOND(!save_path.empty()); +#endif add_torrent_params p; p.trackers.push_back(tracker_url); diff --git a/test/test_session.cpp b/test/test_session.cpp index f77b3ce3822..65c2703bc88 100644 --- a/test/test_session.cpp +++ b/test/test_session.cpp @@ -126,6 +126,23 @@ TORRENT_TEST(async_add_torrent_deprecated_magnet) } #endif +TORRENT_TEST(async_add_torrent_no_save_path) +{ + settings_pack p = settings(); + p.set_int(settings_pack::alert_mask, ~0); + lt::session ses(p); + + add_torrent_params atp; + atp.info_hashes.v1.assign("abababababababababab"); + atp.save_path = ""; + TEST_THROW(ses.add_torrent(atp)); + TEST_THROW(ses.async_add_torrent(atp)); + + lt::error_code ec; + ses.add_torrent(atp, ec); + TORRENT_ASSERT(ec == error_code(lt::errors::invalid_save_path)); +} + TORRENT_TEST(async_add_torrent_duplicate_error) { settings_pack p = settings(); From b5bbe057b7eaf1197467aabc0f60b1a198de7d35 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 28 Jan 2025 13:08:27 +0100 Subject: [PATCH 9/9] fix clang-tidy warning --- src/session_handle.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/session_handle.cpp b/src/session_handle.cpp index 3cc1a29dd64..82032f76a80 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -347,12 +347,8 @@ namespace { #ifndef BOOST_NO_EXCEPTIONS torrent_handle session_handle::add_torrent(add_torrent_params&& params) { -#ifndef BOOST_NO_EXCEPTIONS if (params.save_path.empty()) aux::throw_ex(error_code(errors::invalid_save_path)); -#else - TORRENT_ASSERT_PRECOND(!params.save_path.empty()); -#endif #if TORRENT_ABI_VERSION < 3 if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti)