After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 680823 - g_file_make_directory_with_parents: Fix error propagation
g_file_make_directory_with_parents: Fix error propagation
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2012-07-30 11:34 UTC by Owen Taylor
Modified: 2012-08-16 22:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
g_file_make_directory_with_parents: Fix error propagation (1.40 KB, patch)
2012-07-30 11:35 UTC, Owen Taylor
committed Details | Review
g_file_make_directory_with_parents: refix error propagation (1.14 KB, patch)
2012-08-14 15:04 UTC, Owen Taylor
accepted-commit_now Details | Review
g_file_make_directory_with_parents(): fix a corner case (967 bytes, patch)
2012-08-14 15:28 UTC, Owen Taylor
accepted-commit_now Details | Review
g_file_make_directory_with_parents: clean up logic (2.84 KB, patch)
2012-08-14 15:28 UTC, Owen Taylor
reviewed Details | Review
g_file_make_directory_with_parents: clean up logic (2.84 KB, patch)
2012-08-14 16:58 UTC, Owen Taylor
accepted-commit_now Details | Review
Add tests for g_file_make_directory_with_parents() (3.85 KB, patch)
2012-08-14 16:59 UTC, Owen Taylor
reviewed Details | Review
Add tests for g_file_make_directory_with_parents() (4.07 KB, patch)
2012-08-14 19:40 UTC, Owen Taylor
accepted-commit_now Details | Review
Add tests for g_file_make_directory_with_parents() (4.07 KB, patch)
2012-08-16 22:10 UTC, Matthias Clasen
committed Details | Review
g_file_make_directory_with_parents: clean up logic (2.84 KB, patch)
2012-08-16 22:10 UTC, Matthias Clasen
committed Details | Review
g_file_make_directory_with_parents(): fix a corner case (964 bytes, patch)
2012-08-16 22:10 UTC, Matthias Clasen
committed Details | Review
g_file_make_directory_with_parents: refix error propagation (1.14 KB, patch)
2012-08-16 22:10 UTC, Matthias Clasen
committed Details | Review

Description Owen Taylor 2012-07-30 11:34:57 UTC
When creating a directory fails for some reason other than
the parent not existing, don't clear the error before we try
to propagate it.

To reproduce, run 'ostadmin init /ostree' or otherwise try to
run the function on a directory with a parent directory where the
current user is not allowed to write.
Comment 1 Owen Taylor 2012-07-30 11:35:00 UTC
Created attachment 219879 [details] [review]
g_file_make_directory_with_parents: Fix error propagation
Comment 2 Colin Walters 2012-07-30 14:21:49 UTC
This is probably a regression introduced by

commit 5a57144d5749efaf3b5e752db9b041597d4b062f
Author: Colin Walters <walters@verbum.org>
Date:   Fri May 4 10:03:12 2012 -0400

    gfile: Plug memory leak in g_file_make_directory_with_parents()
Comment 3 Colin Walters 2012-07-30 14:25:21 UTC
Review of attachment 219879 [details] [review]:

Makes sense.
Comment 4 Owen Taylor 2012-07-30 16:33:18 UTC
Attachment 219879 [details] pushed as b0bce4a - g_file_make_directory_with_parents: Fix error propagation
Comment 5 Sebastien Bacher 2012-08-14 14:52:36 UTC
random applications started segfaulting in g_file_make_directory_with_parents() with the recent GNOME 3.5 updates, it seems that commit might be to blame

example, http://redmine.yorba.org/issues/5656 (shotwell didn't change since GNOME 3.4)

stacktrace, https://launchpadlibrarian.net/112502489/Stacktrace.txt
Comment 6 Owen Taylor 2012-08-14 15:04:03 UTC
Created attachment 221154 [details] [review]
g_file_make_directory_with_parents: refix error propagation

The patch from b0bce4ad triggered segfaults - see:

 http://redmine.yorba.org/issues/5656

We were clearing the error before dereferencing it in the next
go-around of the while loop - this wasn't necessary.
Comment 7 Colin Walters 2012-08-14 15:11:04 UTC
Review of attachment 221154 [details] [review]:

But don't we need to clear the error in the case where !result && my_error->code == G_IO_ERROR_NOT_FOUND at the end of the loop? 

Actually...I think this code would be a *lot* cleaner if we eliminated the result boolean, and just used my_error != NULL.
Comment 8 Owen Taylor 2012-08-14 15:21:24 UTC
(In reply to comment #7)
> Review of attachment 221154 [details] [review]:
> 
> But don't we need to clear the error in the case where !result &&
> my_error->code == G_IO_ERROR_NOT_FOUND at the end of the loop?

if '!result && my_error->code == G_IO_ERROR_NOT_FOUND then the loop doesn't end immediately - it contines and the error is cleared. I suppose that then you need to consider what happens if fails:

      parent_file = g_file_get_parent (work_file);
      if (parent_file == NULL)
        break;

the code currently would return a FALSE result but no error and the calling code would likely segfault - g_file_get_parent (work_file) means "work file is the root of the file system" -  yet doesn't exist... which is certainly pathological but maybe it's better to move the g_clear_error() down a few lines, so the whole function fails with G_IO_ERROR_NOT_FOUND in that case.

> Actually...I think this code would be a *lot* cleaner if we eliminated the
> result boolean, and just used my_error != NULL.

Yeah, perhaps.
Comment 9 Owen Taylor 2012-08-14 15:28:20 UTC
Created attachment 221160 [details] [review]
g_file_make_directory_with_parents(): fix a corner case

If g_file_get_parent() unexpectedly failed, we could return
FALSE but with no error.
Comment 10 Owen Taylor 2012-08-14 15:28:23 UTC
Created attachment 221161 [details] [review]
g_file_make_directory_with_parents: clean up logic

Simplify logic by only looking at whether we have a GError and
not also using return codes.
Comment 11 Colin Walters 2012-08-14 15:31:57 UTC
Review of attachment 221154 [details] [review]:

Ok.
Comment 12 Colin Walters 2012-08-14 15:35:45 UTC
Review of attachment 221160 [details] [review]:

This looks safe, yes.
Comment 13 Colin Walters 2012-08-14 15:37:07 UTC
Review of attachment 221161 [details] [review]:

::: gio/gfile.c
@@ +3375,3 @@
       if (my_error)
         g_propagate_error (error, my_error);
+      return my_error != NULL;

This should be: return my_error == NULL;
Comment 14 Owen Taylor 2012-08-14 16:58:28 UTC
Created attachment 221177 [details] [review]
g_file_make_directory_with_parents: clean up logic

Simplify logic by only looking at whether we have a GError and
not also using return codes.
Comment 15 Owen Taylor 2012-08-14 16:59:18 UTC
Created attachment 221178 [details] [review]
Add tests for g_file_make_directory_with_parents()

Add tests to catch recent regressions with g_file_make_directory_with_parents()

This is tested to catch the original two regressions and the bug I tried
to introduce with the 'clean up logic' patch.
Comment 16 Colin Walters 2012-08-14 18:33:39 UTC
Review of attachment 221177 [details] [review]:

Looks good.
Comment 17 Colin Walters 2012-08-14 18:35:51 UTC
Review of attachment 221178 [details] [review]:

::: gio/tests/live-g-file.c
@@ +1046,3 @@
+
+  g_assert (test_data != NULL);
+  log ("\n");

Why is this here?

@@ +1093,3 @@
+  /* No obvious way to do this on Windows */
+  if (!posix_compat)
+    return;

Should probably be "goto out;" so that we don't leak memory on Windows either.

@@ +1118,3 @@
+  g_object_unref (greatgrandchild);
+  g_object_unref (grandchild);
+  g_object_unref (child);

g_object_unref (root); too
Comment 18 Owen Taylor 2012-08-14 19:40:38 UTC
Created attachment 221186 [details] [review]
Add tests for g_file_make_directory_with_parents()

New version with fixes. The log("\n") was there because I started from a
different test which had verbose logging and wanted that to be on a
different line than <testname>: - removed.
Comment 19 Colin Walters 2012-08-14 20:15:54 UTC
Review of attachment 221186 [details] [review]:

Looks reasonable to me.
Comment 20 Matthias Clasen 2012-08-16 22:10:24 UTC
The following fixes have been pushed:
d7e1d51 Add tests for g_file_make_directory_with_parents()
f899358 g_file_make_directory_with_parents: clean up logic
5291190 g_file_make_directory_with_parents(): fix a corner case
732470a g_file_make_directory_with_parents: refix error propagation
Comment 21 Matthias Clasen 2012-08-16 22:10:27 UTC
Created attachment 221506 [details] [review]
Add tests for g_file_make_directory_with_parents()

Add tests to catch recent regressions with g_file_make_directory_with_parents()
Comment 22 Matthias Clasen 2012-08-16 22:10:31 UTC
Created attachment 221507 [details] [review]
g_file_make_directory_with_parents: clean up logic

Simplify logic by only looking at whether we have a GError and
not also using return codes.
Comment 23 Matthias Clasen 2012-08-16 22:10:34 UTC
Created attachment 221508 [details] [review]
g_file_make_directory_with_parents(): fix a corner case

If g_file_get_parent() unexpectedly failed, we could return
FALSE but with no error.
Comment 24 Matthias Clasen 2012-08-16 22:10:38 UTC
Created attachment 221509 [details] [review]
g_file_make_directory_with_parents: refix error propagation

The patch from b0bce4ad triggered segfaults - see:

 http://redmine.yorba.org/issues/5656

We were clearing the error before dereferencing it in the next
go-around of the while loop - this wasn't necessary.