From 8b57f10b0f58998194907490971b1faaccc95f28 Mon Sep 17 00:00:00 2001 From: arvidn Date: Mon, 30 Sep 2024 18:44:25 +0200 Subject: [PATCH] fix piece size check when loading torrents --- ChangeLog | 1 + include/libtorrent/piece_picker.hpp | 4 ++-- src/torrent_info.cpp | 9 ++++++++- test/test_torrent.cpp | 21 ++++++++++++++++----- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 919dc238e50..980922ed9a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix piece size check when loading torrents * back-port fix last_upload and last_download resume data fields to use posix time * back-port treat CGNAT address range as local IPs diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index dec5c9f211c..5b7cda42bd4 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -97,9 +97,9 @@ namespace libtorrent { // priority factor prio_factor = 3, // max blocks per piece - // there are counters in downloading_piece that only have 15 bits to + // there are counters in downloading_piece that only have 14 bits to // count blocks per piece, that's restricting this - max_blocks_per_piece = (1 << 15) - 1 + max_blocks_per_piece = (1 << 14) - 1 }; struct block_info diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 94a8c328526..e0fe56d460a 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -53,6 +53,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/announce_entry.hpp" #include "libtorrent/hex.hpp" // to_hex #include "libtorrent/aux_/numeric_cast.hpp" +#include "libtorrent/piece_picker.hpp" +#include "libtorrent/disk_interface.hpp" // for default_block_size #if TORRENT_ABI_VERSION == 1 #include "libtorrent/lazy_entry.hpp" @@ -1027,11 +1029,16 @@ namespace { // extract piece length std::int64_t piece_length = info.dict_find_int_value("piece length", -1); - if (piece_length <= 0 || piece_length > std::numeric_limits::max()) + if (piece_length <= 0) { ec = errors::torrent_missing_piece_length; return false; } + if (piece_length > piece_picker::max_blocks_per_piece * default_block_size) + { + ec = errors::invalid_piece_size; + return false; + } file_storage files; files.set_piece_length(static_cast(piece_length)); diff --git a/test/test_torrent.cpp b/test/test_torrent.cpp index 3f308f91f7a..fc7a568a0f2 100644 --- a/test/test_torrent.cpp +++ b/test/test_torrent.cpp @@ -167,7 +167,7 @@ void test_running_torrent(std::shared_ptr info, std::int64_t file_ TEST_CHECK(h.get_file_priorities() == prio); } -void test_large_piece_size(int const size) +void test_large_piece_size(std::int64_t const size) { entry torrent; entry& info = torrent["info"]; @@ -179,7 +179,15 @@ void test_large_piece_size(int const size) std::vector buf; bencode(std::back_inserter(buf), torrent); add_torrent_params atp; - atp.ti = std::make_shared(buf, from_span); + try + { + atp.ti = std::make_shared(buf, from_span); + } + catch (lt::system_error const& e) + { + TEST_CHECK(e.code() == error_code(lt::errors::invalid_piece_size)); + return; + } atp.save_path = "."; lt::session ses; @@ -212,9 +220,12 @@ TORRENT_TEST(long_names) TORRENT_TEST(large_piece_size) { - test_large_piece_size(32768 * 16 * 1024); - test_large_piece_size(65536 * 16 * 1024); - test_large_piece_size(65537 * 16 * 1024); + test_large_piece_size(0xfffc000 + 0x4000); + test_large_piece_size(0x10000000); + test_large_piece_size(0x20000000); + test_large_piece_size(0x40000000); + test_large_piece_size(0x80000000); + test_large_piece_size(0x100000000); } TORRENT_TEST(total_wanted)