Bug 593406 - Permissions set to 777 after copying via Nautilus
authorBenjamin Otte <otte@gnome.org>
Tue, 1 Sep 2009 09:54:48 +0000 (11:54 +0200)
committerBenjamin Otte <otte@gnome.org>
Tue, 1 Sep 2009 10:15:31 +0000 (12:15 +0200)
When doing a g_file_copy() with nofollow-symlinks (to copy a link for
example), the later copying of the file attributes copies the source
links 777 attributes to the target's attributes. As chmod affects the
symlink target, this would cause such copies to always set the target to
777 mode.

This patch makes setting the mode with nofollow-symlinks fail with
NOT_SUPPORTED.

The aforementioned g_file_copy() will still succeed, because it ignores
errors of the attribute copy.

gio/glocalfileinfo.c

index 72a59b5e47ad63bc9996f5300b1a6d83f644af08..7933ed96a1312b6972ee829a55ab9d1957d4003f 100644 (file)
@@ -1869,6 +1869,7 @@ get_string (const GFileAttributeValue  *value,
 
 static gboolean
 set_unix_mode (char                       *filename,
+               GFileQueryInfoFlags         flags,
               const GFileAttributeValue  *value,
               GError                    **error)
 {
@@ -1877,6 +1878,13 @@ set_unix_mode (char                       *filename,
   if (!get_uint32 (value, &val, error))
     return FALSE;
   
+  if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) {
+    g_set_error_literal (error, G_IO_ERROR,
+                         G_IO_ERROR_NOT_SUPPORTED,
+                         _("Cannot set permissions on symlinks"));
+    return FALSE;
+  }
+
   if (g_chmod (filename, val) == -1)
     {
       int errsv = errno;
@@ -2172,7 +2180,7 @@ _g_local_file_info_set_attribute (char                 *filename,
   _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE);
   
   if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0)
-    return set_unix_mode (filename, &value, error);
+    return set_unix_mode (filename, flags, &value, error);
   
 #ifdef HAVE_CHOWN
   else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0)
@@ -2316,7 +2324,7 @@ _g_local_file_info_set_attributes  (char                 *filename,
   value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE);
   if (value)
     {
-      if (!set_unix_mode (filename, value, error))
+      if (!set_unix_mode (filename, flags, value, error))
        {
          value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
          res = FALSE;