diff --git a/ChangeLog b/ChangeLog index 89ca5a3c4..74f5398a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 1.1.5 release + * fix parsing of torrents with certain invalid filenames * fix leak of torrent_peer objecs (entries in peer_list) * fix leak of peer_class objects (when setting per-torrent rate limits) * expose peer_class API to python binding diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index aa17bc258..b83043725 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -431,6 +431,7 @@ namespace libtorrent if (p && p.list_size() > 0) { + std::size_t const orig_path_len = path.size(); int const preallocate = path.size() + path_length(p, ec); if (ec) return false; path.reserve(preallocate); @@ -450,6 +451,14 @@ namespace libtorrent } sanitize_append_path_element(path, e.string_ptr(), e.string_length()); } + + // if all path elements were sanitized away, we need to use another + // name instead + if (path.size() == orig_path_len) + { + path += TORRENT_SEPARATOR; + path += "_"; + } } else if (file_flags & file_storage::flag_pad_file) { diff --git a/test/Makefile.am b/test/Makefile.am index f41a95901..7aab670e1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -109,6 +109,8 @@ EXTRA_DIST = Jamfile \ test_torrents/url_seed_multi_space.torrent \ test_torrents/url_seed_multi_space_nolist.torrent \ test_torrents/whitespace_url.torrent \ + test_torrents/invalid_filename.torrent \ + test_torrents/invalid_filename2.torrent \ mutable_test_torrents/test1.torrent \ mutable_test_torrents/test1_pad_files.torrent \ mutable_test_torrents/test1_single.torrent\ diff --git a/test/test_torrent_info.cpp b/test/test_torrent_info.cpp index 2311750b2..8d3b4966b 100644 --- a/test/test_torrent_info.cpp +++ b/test/test_torrent_info.cpp @@ -134,6 +134,8 @@ static test_torrent_t test_torrents[] = { "unordered.torrent" }, { "symlink_zero_size.torrent" }, { "pad_file_no_path.torrent" }, + { "invalid_filename.torrent" }, + { "invalid_filename2.torrent" }, }; struct test_failing_torrent_t @@ -769,6 +771,14 @@ TORRENT_TEST(parse_torrents) TEST_EQUAL(ti->num_files(), 2); TEST_EQUAL(ti->files().file_path(1), combine_path(".pad", "0")); } + else if (std::string(test_torrents[i].file) == "invalid_filename.torrent") + { + TEST_EQUAL(ti->num_files(), 2); + } + else if (std::string(test_torrents[i].file) == "invalid_filename2.torrent") + { + TEST_EQUAL(ti->num_files(), 3); + } file_storage const& fs = ti->files(); for (int i = 0; i < fs.num_files(); ++i) diff --git a/test/test_torrents/invalid_filename.torrent b/test/test_torrents/invalid_filename.torrent new file mode 100644 index 000000000..6e2bfc5ea --- /dev/null +++ b/test/test_torrents/invalid_filename.torrent @@ -0,0 +1 @@ +d10:created by10:libtorrent13:creation datei1419490173e4:infod5:filesld6:lengthi51200e4:pathl1:feed6:lengthi14336e4:pathl1:.eee4:name5:\est212:piece lengthi16384e6:pieces80:01234567890123456789012345678901234567890123456789012345678901234567890123456789ee diff --git a/test/test_torrents/invalid_filename2.torrent b/test/test_torrents/invalid_filename2.torrent new file mode 100644 index 000000000..b63e17484 --- /dev/null +++ b/test/test_torrents/invalid_filename2.torrent @@ -0,0 +1 @@ +d10:created by10:libtorrent13:creation datei1419490173e4:infod5:filesld6:lengthi51200e4:pathl1:feed6:lengthi14335e4:pathl1:.1:.eed6:lengthi1e4:pathl1:/1:.eee4:name5:\est212:piece lengthi16384e6:pieces80:01234567890123456789012345678901234567890123456789012345678901234567890123456789ee