From 88e4e0a97b07aa1445e55b74e078423b99c8bb51 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 5 Dec 2013 07:40:57 +0000 Subject: [PATCH] strip trailing dots and spaces in filenames --- src/torrent_info.cpp | 64 +++++++++++++++--------- test/test_torrent_parse.cpp | 5 ++ test/test_torrents/invalid_name3.torrent | 1 + 3 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 test/test_torrents/invalid_name3.torrent diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index a4bfd510d..5bd1a135a 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -195,47 +195,61 @@ namespace libtorrent // on windows, the max path is expressed in // unicode characters, not bytes -#if defined TORRENT_WINDOWS +#if defined TORRENT_WINDOWS && TORRENT_USE_WSTRING std::wstring path_element; utf8_wchar(element, path_element); - if (path_element.size() <= max_path_len) return; - - // truncate filenames that are too long. But keep extensions! - std::wstring ext; - wchar_t const* ext1 = wcsrchr(path_element.c_str(), '.'); - if (ext1 != NULL) ext = ext1; - - if (ext.size() > 15) + if (path_element.size() > max_path_len) { - path_element.resize(max_path_len); - } - else - { - path_element.resize(max_path_len - ext.size()); - path_element += ext; + // truncate filenames that are too long. But keep extensions! + std::wstring ext; + wchar_t const* ext1 = wcsrchr(path_element.c_str(), '.'); + if (ext1 != NULL) ext = ext1; + + if (ext.size() > 15) + { + path_element.resize(max_path_len); + } + else + { + path_element.resize(max_path_len - ext.size()); + path_element += ext; + } } // remove trailing spaces and dots. These aren't allowed in filenames on windows for (int i = path_element.size() - 1; i >= 0; --i) { if (path_element[i] != L' ' && path_element[i] != L'.') break; - path_element[i] = L'_'; + path_element.resize(i); } + if (path_element.empty()) path_element = L"_"; wchar_utf8(path_element, element); #else std::string& path_element = element; - if (int(path_element.size()) <= max_path_len) return; + if (int(path_element.size()) > max_path_len) + { - // truncate filenames that are too long. But keep extensions! - std::string ext = extension(path_element); - if (ext.size() > 15) - { - path_element.resize(max_path_len); + // truncate filenames that are too long. But keep extensions! + std::string ext = extension(path_element); + if (ext.size() > 15) + { + path_element.resize(max_path_len); + } + else + { + path_element.resize(max_path_len - ext.size()); + path_element += ext; + } } - else + + // remove trailing spaces and dots. These aren't allowed in filenames on windows + // apply rules consistently across platforms though + for (int i = path_element.size() - 1; i >= 0; --i) { - path_element.resize(max_path_len - ext.size()); - path_element += ext; + if (path_element[i] != ' ' && path_element[i] != '.') break; + path_element.resize(i); } + + if (path_element.empty()) path_element = "_"; #endif } diff --git a/test/test_torrent_parse.cpp b/test/test_torrent_parse.cpp index 9b98f276a..2f6ffc015 100644 --- a/test/test_torrent_parse.cpp +++ b/test/test_torrent_parse.cpp @@ -72,6 +72,7 @@ test_torrent_t test_torrents[] = { "url_seed_multi_space_nolist.torrent" }, { "root_hash.torrent" }, { "empty_path_multi.torrent" }, + { "invalid_name3.torrent" }, }; struct test_failing_torrent_t @@ -423,6 +424,10 @@ int test_main() TEST_EQUAL(ti->url_seeds()[0], "http://test.com/test%20file/foo%20bar/"); #endif } + else if (std::string(test_torrents[i].file) == "invalid_name3.torrent") + { + TEST_EQUAL(ti->name(), "foobar"); + } file_storage const& fs = ti->files(); for (int i = 0; i < fs.num_files(); ++i) diff --git a/test/test_torrents/invalid_name3.torrent b/test/test_torrents/invalid_name3.torrent new file mode 100644 index 000000000..105c496bc --- /dev/null +++ b/test/test_torrents/invalid_name3.torrent @@ -0,0 +1 @@ +d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi425e4:pathl3:foo7:bar.txteed6:lengthi425e4:pathl3:foo7:var.txteee4:name7:foobar 12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW›}ÜA4u,·¼‘‡ee