From 40fc03110623ccd622140d58529a0eb13b87b17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= Date: Sat, 25 Dec 2021 22:01:19 +0000 Subject: file-operations: Prevent overriding source on move This had been fixed but only for the fallback implementation, as per 100781f806b922cf6b959ec663a196a47b6eb71e As a result, when moving a file/folder to its current location, the default implementation still tries g_file_move(), which obviously fails with a conflict, then presents the user the conflict dialog. Then: - for a file, if the user chooses "Replace", then g_file_move() proceeds to replace the file with itself, which is... useless at best. - for a folder, if the user chooses "Merge", g_file_move() still fails because it doesn't support merging, so we try the fallback implementation which, finally, warns the user that this is not allowed. So, the first case is useless and the second case asks the user if they want to perform an action which is not allowed anyway. This issue is reproducible using the "Move to..." action. So, copy the fix to the g_file_move() path. It's probably an oversight of the original fix that it was done for only one path. --- src/nautilus-file-operations.c | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/nautilus-file-operations.c') diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c index 72ae0d2c8..73893d7f4 100644 --- a/src/nautilus-file-operations.c +++ b/src/nautilus-file-operations.c @@ -6274,6 +6274,51 @@ move_file_prepare (CopyMoveJob *move_job, goto out; } + /* Don't allow moving over the source or one of the parents of the source. + */ + if (test_dir_is_parent (src, dest)) + { + int response; + + if (job->skip_all_error) + { + goto out; + } + + /* the run_warning() frees all strings passed in automatically */ + primary = move_job->is_move ? g_strdup (_("You cannot move a file over itself.")) + : g_strdup (_("You cannot copy a file over itself.")); + secondary = g_strdup (_("The source file would be overwritten by the destination.")); + + response = run_warning (job, + primary, + secondary, + NULL, + files_left > 1, + CANCEL, SKIP_ALL, SKIP, + NULL); + + if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) + { + abort_job (job); + } + else if (response == 1) /* skip all */ + { + job->skip_all_error = TRUE; + } + else if (response == 2) /* skip */ + { + /* do nothing */ + } + else + { + g_assert_not_reached (); + } + + goto out; + } + + retry: flags = G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_NO_FALLBACK_FOR_MOVE; -- cgit v1.2.1