clean up and fix edge cases in update_path_index

This commit is contained in:
arvidn 2017-10-01 03:17:10 +02:00 committed by Arvid Norberg
parent 17d78d3b8f
commit 5026659cb6
3 changed files with 45 additions and 14 deletions

View File

@ -509,6 +509,7 @@ namespace libtorrent {
// low-level function. returns a pointer to the internal storage for // low-level function. returns a pointer to the internal storage for
// the filename. This string may not be 0-terminated! // the filename. This string may not be 0-terminated!
// the ``file_name_len()`` function returns the length of the filename. // the ``file_name_len()`` function returns the length of the filename.
// prefer to use ``file_name()`` instead, which returns a ``string_view``.
char const* file_name_ptr(file_index_t index) const; char const* file_name_ptr(file_index_t index) const;
int file_name_len(file_index_t index) const; int file_name_len(file_index_t index) const;

View File

@ -131,34 +131,37 @@ namespace {
// sorry about this messy string handling, but I did // sorry about this messy string handling, but I did
// profile it, and it was expensive // profile it, and it was expensive
char const* leaf = filename_cstr(path.c_str()); char const* leaf = filename_cstr(path.c_str());
char const* branch_path = ""; string_view branch_path;
int branch_len = 0;
if (leaf > path.c_str()) if (leaf > path.c_str())
{ {
// split the string into the leaf filename // split the string into the leaf filename
// and the branch path // and the branch path
branch_path = path.c_str(); branch_path = path;
branch_len = int(leaf - path.c_str()); branch_path = branch_path.substr(0
, static_cast<std::size_t>(leaf - path.c_str()));
// trim trailing slashes // trim trailing slashes
if (branch_len > 0 && branch_path[branch_len - 1] == TORRENT_SEPARATOR) while (!branch_path.empty() && branch_path.back() == TORRENT_SEPARATOR)
--branch_len; {
branch_path.remove_suffix(1);
}
} }
if (branch_len <= 0) if (branch_path.empty())
{ {
if (set_name) e.set_name(leaf); if (set_name) e.set_name(leaf);
e.path_index = -1; e.path_index = -1;
return; return;
} }
if (branch_len >= int(m_name.size()) if (branch_path.size() >= m_name.size()
&& std::memcmp(branch_path, m_name.c_str(), m_name.size()) == 0 && branch_path.substr(0, m_name.size()) == m_name
&& branch_path[m_name.size()] == TORRENT_SEPARATOR) && branch_path[m_name.size()] == TORRENT_SEPARATOR)
{ {
int const offset = int(m_name.size()) branch_path.remove_prefix(m_name.size());
+ (int(m_name.size()) == branch_len ? 0 : 1); while (!branch_path.empty() && branch_path.front() == TORRENT_SEPARATOR)
branch_path += offset; {
branch_len -= offset; branch_path.remove_prefix(1);
}
e.no_root_dir = false; e.no_root_dir = false;
} }
else else
@ -166,7 +169,7 @@ namespace {
e.no_root_dir = true; e.no_root_dir = true;
} }
e.path_index = get_or_add_path({branch_path, aux::numeric_cast<std::size_t>(branch_len)}); e.path_index = get_or_add_path(branch_path);
if (set_name) e.set_name(leaf); if (set_name) e.set_name(leaf);
} }

View File

@ -183,6 +183,7 @@ TORRENT_TEST(pointer_offset)
// test filename_ptr and filename_len // test filename_ptr and filename_len
TEST_EQUAL(st.file_name_ptr(file_index_t{0}), filename); TEST_EQUAL(st.file_name_ptr(file_index_t{0}), filename);
TEST_EQUAL(st.file_name_len(file_index_t{0}), 5); TEST_EQUAL(st.file_name_len(file_index_t{0}), 5);
TEST_EQUAL(st.file_name(file_index_t{0}), string_view(filename, 5));
TEST_EQUAL(st.file_path(file_index_t{0}, ""), combine_path("test-torrent-1", "test1")); TEST_EQUAL(st.file_path(file_index_t{0}, ""), combine_path("test-torrent-1", "test1"));
TEST_EQUAL(st.file_path(file_index_t{0}, "tmp"), combine_path("tmp" TEST_EQUAL(st.file_path(file_index_t{0}, "tmp"), combine_path("tmp"
@ -202,6 +203,32 @@ TORRENT_TEST(pointer_offset)
TEST_EQUAL(st.file_name_len(file_index_t{0}), 5); TEST_EQUAL(st.file_name_len(file_index_t{0}), 5);
} }
TORRENT_TEST(invalid_path1)
{
file_storage st;
#ifdef TORRENT_WINDOWS
st.add_file_borrow({}, R"(+\\\()", 10);
#else
st.add_file_borrow({}, "+///(", 10);
#endif
TEST_EQUAL(st.file_name(file_index_t{0}), "(");
TEST_EQUAL(st.file_path(file_index_t{0}, ""), combine_path("+", "("));
}
TORRENT_TEST(invalid_path2)
{
file_storage st;
#ifdef TORRENT_WINDOWS
st.add_file_borrow({}, R"(+\\\+\\()", 10);
#else
st.add_file_borrow({}, "+///+//(", 10);
#endif
TEST_EQUAL(st.file_name(file_index_t{0}), "(");
TEST_EQUAL(st.file_path(file_index_t{0}, ""), combine_path("+", combine_path("+", "(")));
}
TORRENT_TEST(map_file) TORRENT_TEST(map_file)
{ {
// test map_file // test map_file