From cc8a2c24e99f5fc690e604738831667367b3fc3f Mon Sep 17 00:00:00 2001 From: Reuben Green Date: Fri, 16 Aug 2019 14:06:32 +0100 Subject: [PATCH 1/2] Fix possible memory leak Adds some calls to g_object_unref to the code in thunar_transfer_job_execute which moves files out of the trash, in order to prevent possible memory leaks when such a move operation is canceled. --- thunar/thunar-transfer-job.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c index cfa932ad..4abe42a5 100644 --- a/thunar/thunar-transfer-job.c +++ b/thunar/thunar-transfer-job.c @@ -923,6 +923,7 @@ thunar_transfer_job_execute (ExoJob *job, if (exo_job_set_error_if_cancelled (job, &err)) { g_object_unref (target_parent); + g_object_unref (info); break; } @@ -946,6 +947,7 @@ thunar_transfer_job_execute (ExoJob *job, { g_object_unref (target_parent); g_free (parent_display_name); + g_object_unref (info); break; } @@ -966,6 +968,7 @@ thunar_transfer_job_execute (ExoJob *job, g_object_unref (target_parent); g_free (parent_display_name); + g_object_unref (info); break; } -- 2.23.0.rc1 From 1f6f89e473612365a40dc7489b81bd572e45f139 Mon Sep 17 00:00:00 2001 From: Reuben Green Date: Fri, 16 Aug 2019 14:34:22 +0100 Subject: [PATCH 2/2] Prevent unnecessary fallback copy-delete in file move when overwriting Allows the use of native filesystem move (rather than a copy-and-delete-fallback) when overwriting files in a file move, with the user having the option (via a thunar_job_ask_replace dialog box) to replace or skip files, or else cancel the whole operation. (Bug #15727) --- thunar/thunar-transfer-job.c | 63 ++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c index 4abe42a5..1e9ad76a 100644 --- a/thunar/thunar-transfer-job.c +++ b/thunar/thunar-transfer-job.c @@ -854,6 +854,7 @@ thunar_transfer_job_execute (ExoJob *job, GFileInfo *info; GFileCopyFlags flags; gboolean parent_exists; + gboolean move_successful; GError *err = NULL; GList *new_files_list = NULL; GList *snext; @@ -986,10 +987,40 @@ thunar_transfer_job_execute (ExoJob *job, exo_job_info_message (job, _("Trying to move \"%s\""), g_file_info_get_display_name (info)); - if (g_file_move (node->source_file, tp->data, - flags, - exo_job_get_cancellable (job), - NULL, NULL, &err)) + /* try moving without overwriting */ + move_successful = g_file_move (node->source_file, tp->data, + flags, + exo_job_get_cancellable (job), + NULL, NULL, &err); + + /* if the file already exists, ask the user if they want to overwrite it */ + response = THUNAR_JOB_RESPONSE_YES; + if (!move_successful && err->code == G_IO_ERROR_EXISTS) + { + g_clear_error (&err); + response = thunar_job_ask_replace (THUNAR_JOB (job), node->source_file, tp->data, NULL); + + /* if the user chose to overwrite then try to do so */ + if (response == THUNAR_JOB_RESPONSE_YES) + move_successful = g_file_move (node->source_file, tp->data, + flags | G_FILE_COPY_OVERWRITE, + exo_job_get_cancellable (job), + NULL, NULL, &err); + + /* if the user chose to cancel then abort all remaining file moves */ + if (response == THUNAR_JOB_RESPONSE_CANCEL) + { + /* release all the remaining source and target files, and free the lists */ + g_list_free_full (transfer_job->source_node_list, thunar_transfer_node_free); + transfer_job->source_node_list = NULL; + g_list_free_full (transfer_job->target_file_list, g_object_unref); + transfer_job->target_file_list= NULL; + g_object_unref (info); + break; + } + } + + if (move_successful) { /* notify the thumbnail cache of the move operation */ thunar_thumbnail_cache_move_file (thumbnail_cache, @@ -998,16 +1029,10 @@ thunar_transfer_job_execute (ExoJob *job, /* add the target file to the new files list */ new_files_list = thunar_g_file_list_prepend (new_files_list, tp->data); - - /* release source and target files */ - thunar_transfer_node_free (node); - g_object_unref (tp->data); - - /* drop the matching list items */ - transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp); - transfer_job->target_file_list = g_list_delete_link (transfer_job->target_file_list, tp); } - else if (!exo_job_is_cancelled (job)) + + /* if the file moves failed but the user confirmed them, prepare for the fallback copy and delete */ + if (!move_successful && response == THUNAR_JOB_RESPONSE_YES) { g_clear_error (&err); @@ -1023,7 +1048,18 @@ thunar_transfer_job_execute (ExoJob *job, break; } } + else + { + /* release source and target files */ + thunar_transfer_node_free (node); + g_object_unref (tp->data); + + /* drop the matching list items */ + transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp); + transfer_job->target_file_list = g_list_delete_link (transfer_job->target_file_list, tp); + } } + else if (transfer_job->type == THUNAR_TRANSFER_JOB_COPY) { if (!thunar_transfer_job_collect_node (THUNAR_TRANSFER_JOB (job), node, &err)) @@ -1221,4 +1257,3 @@ thunar_transfer_job_get_status (ThunarTransferJob *job) return g_string_free (status, FALSE); } - -- 2.23.0.rc1