From 504b77b0b9925616be8d080a98f0a4fc04ebe9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=A7=D0=B0?= =?UTF-8?q?=D0=B9?= Date: Mon, 19 Jun 2023 09:30:55 +0400 Subject: [PATCH] fix: return error when renaming into existing file (#5563) --- libtransmission/torrent.cc | 34 ++++++++++++++++++++++++---- tests/libtransmission/rename-test.cc | 3 +++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index 73a817265..e93371598 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -2448,10 +2448,36 @@ namespace { namespace rename_helpers { -bool renameArgsAreValid(std::string_view oldpath, std::string_view newname) +bool renameArgsAreValid(tr_torrent const* tor, std::string_view oldpath, std::string_view newname) { - return !std::empty(oldpath) && !std::empty(newname) && newname != "."sv && newname != ".."sv && - !tr_strvContains(newname, TR_PATH_DELIMITER); + if (std::empty(oldpath) || std::empty(newname) || newname == "."sv || newname == ".."sv || + tr_strvContains(newname, TR_PATH_DELIMITER)) + { + return false; + } + + auto const newpath = tr_strvContains(oldpath, TR_PATH_DELIMITER) ? + tr_pathbuf{ tr_sys_path_dirname(oldpath), '/', newname } : + tr_pathbuf{ newname }; + + if (newpath == oldpath) + { + return true; + } + + auto const newpath_as_dir = tr_pathbuf{ newpath, '/' }; + auto const n_files = tor->file_count(); + + for (tr_file_index_t i = 0; i < n_files; ++i) + { + auto const& name = tor->file_subpath(i); + if (newpath == name || tr_strvStartsWith(name, newpath_as_dir)) + { + return false; + } + } + + return true; } auto renameFindAffectedFiles(tr_torrent const* tor, std::string_view oldpath) @@ -2568,7 +2594,7 @@ void torrentRenamePath( int error = 0; - if (!renameArgsAreValid(oldpath, newname)) + if (!renameArgsAreValid(tor, oldpath, newname)) { error = EINVAL; } diff --git a/tests/libtransmission/rename-test.cc b/tests/libtransmission/rename-test.cc index d038506e5..918133088 100644 --- a/tests/libtransmission/rename-test.cc +++ b/tests/libtransmission/rename-test.cc @@ -414,6 +414,9 @@ TEST_F(RenameTest, multifileTorrent) EXPECT_EQ(EINVAL, torrentRenameAndWait(tor, "Felidae/FelinaeX", "Genus Felinae")); EXPECT_STREQ("Felidae", tr_torrentName(tor)); + // rename filename collision + EXPECT_EQ(EINVAL, torrentRenameAndWait(tor, "Felidae/Felinae/Felis/catus/Kyphi", "Saffron")); + EXPECT_STREQ("Felidae", tr_torrentName(tor)); /*** **** ***/