From 96c62bc4b82c7b660531fe58a187a74acb8ca714 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 28 Feb 2013 03:29:33 +0000 Subject: [PATCH] merged fix from RC_0_16 --- ChangeLog | 1 + src/file_storage.cpp | 28 ++++++++++++++++++++++++---- test/test_storage.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b60b34214..ca90ad18d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * improve file_storage::map_file when dealing with invalid input * improve handling of invalid utf-8 sequences in strings in torrent files * handle more cases of broken .torrent files * fix bug filename collision resolver diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 64d325e74..711decd22 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -283,12 +283,32 @@ namespace libtorrent { TORRENT_ASSERT(file_index < num_files()); TORRENT_ASSERT(file_index >= 0); - size_type offset = file_offset + this->file_offset(file_index); peer_request ret; - ret.piece = int(offset / piece_length()); - ret.start = int(offset % piece_length()); - ret.length = size; + if (file_index < 0 || file_index >= num_files()) + { + ret.piece = m_num_pieces; + ret.start = 0; + ret.length = 0; + return ret; + } + + size_type offset = file_offset + this->file_offset(file_index); + + if (offset >= total_size()) + { + ret.piece = m_num_pieces; + ret.start = 0; + ret.length = 0; + } + else + { + ret.piece = int(offset / piece_length()); + ret.start = int(offset % piece_length()); + ret.length = size; + if (offset + size > total_size()) + ret.length = total_size() - offset; + } return ret; } diff --git a/test/test_storage.cpp b/test/test_storage.cpp index e45bea3cf..f66ee1d30 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -1075,6 +1075,31 @@ int test_main() std::for_each(test_paths.begin(), test_paths.end(), boost::bind(&run_test, _1, true)); std::for_each(test_paths.begin(), test_paths.end(), boost::bind(&run_test, _1, false)); + file_storage fs; + fs.set_piece_length(512); + fs.add_file("temp_storage/test1.tmp", 17); + fs.add_file("temp_storage/test2.tmp", 612); + fs.add_file("temp_storage/test3.tmp", 0); + fs.add_file("temp_storage/test4.tmp", 0); + fs.add_file("temp_storage/test5.tmp", 3253); + // size: 3882 + fs.add_file("temp_storage/test6.tmp", 841); + // size: 4723 + + peer_request rq = fs.map_file(0, 0, 10); + TEST_EQUAL(rq.piece, 0); + TEST_EQUAL(rq.start, 0); + TEST_EQUAL(rq.length, 10); + rq = fs.map_file(5, 0, 10); + TEST_EQUAL(rq.piece, 7); + TEST_EQUAL(rq.start, 298); + TEST_EQUAL(rq.length, 10); + rq = fs.map_file(5, 0, 1000); + TEST_EQUAL(rq.piece, 7); + TEST_EQUAL(rq.start, 298); + TEST_EQUAL(rq.length, 841); + + return 0; }