[gvfs] google: Disable deletion of non-empty directories



commit 07a4695b107a28618ebde9a54193e5b5746b60b1
Author: Mayank Sharma <mayank8019 gmail com>
Date:   Tue Jul 23 15:11:11 2019 +0530

    google: Disable deletion of non-empty directories
    
    Earlier, we were deleting a directory irrespective of whether it
    was empty or not. This would cause a permanent deletion of the
    folder on Drive, and accidental deletions could be catastrophic.
    
    `g_file_delete()` states that if a directory is supposed to be deleted,
    the job should only carry forward to completion if the directory is
    empty, else it should error out. We fix this behaviour of delete
    operation in google backend by conforming to GIO's documentation.

 daemon/gvfsbackendgoogle.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index dcbdc713..1b3cf509 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -1331,6 +1331,7 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
   gchar *entry_path = NULL;
   GList *parent_ids;
   guint parent_ids_len;
+  gchar *id = NULL;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ delete: %s\n", filename);
@@ -1344,6 +1345,39 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
       goto out;
     }
 
+  /* g_strdup() is necessary to prevent segfault because gdata_entry_get_id() calls g_free() */
+  id = g_strdup (gdata_entry_get_id (entry));
+
+  if (GDATA_IS_DOCUMENTS_FOLDER (entry))
+    {
+      GHashTableIter iter;
+      DirEntriesKey *key;
+
+      if (!is_dir_listing_valid (self, entry))
+        {
+          rebuild_dir (self, entry, cancellable, &error);
+          if (error != NULL)
+            {
+              g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+              g_error_free (error);
+              goto out;
+            }
+        }
+
+      g_hash_table_iter_init (&iter, self->dir_entries);
+      while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
+        {
+          if (g_strcmp0 (key->parent_id, id) == 0)
+            {
+              g_vfs_job_failed (G_VFS_JOB (job),
+                                G_IO_ERROR,
+                                G_IO_ERROR_NOT_EMPTY,
+                                _("Directory not empty"));
+              goto out;
+            }
+        }
+    }
+
   parent = resolve_dir (self, filename, cancellable, NULL, NULL, &error);
   if (error != NULL)
     {
@@ -1409,6 +1443,7 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
  out:
   g_clear_object (&new_entry);
   g_free (entry_path);
+  g_free (id);
   g_debug ("- delete\n");
   g_rec_mutex_unlock (&self->mutex);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]