Hello community,

here is the log from the commit of package libdazzle for openSUSE:Factory 
checked in at 2018-02-03 15:39:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libdazzle (Old)
 and      /work/SRC/openSUSE:Factory/.libdazzle.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libdazzle"

Sat Feb  3 15:39:26 2018 rev:5 rq:572090 version:3.26.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/libdazzle/libdazzle.changes      2018-01-25 
12:38:07.901411161 +0100
+++ /work/SRC/openSUSE:Factory/.libdazzle.new/libdazzle.changes 2018-02-03 
15:39:27.749890634 +0100
@@ -1,0 +2,17 @@
+Fri Feb  2 10:28:51 UTC 2018 - [email protected]
+
+- Update to vresion 3.26.3:
+  + A number of fixes to DzlSignalGroup to be more re-entrant safe
+    and handle disposal cycles better.
+  + DzlPreferences is more aggressive about protecting against
+    widget disposal.
+  + A static inline dzl_clear_signal_handler() was backported for
+    use in other backports from master.
+  + A number of protections were added to DzlDirectoryReaper to
+    protect against potentially following through symlinks.
+  + Max age in DzlDirectoryReaper was changed to always ensure a
+    positive value for use in date comparisons.
+  + A leak of GFile instances in the directory reaper was fixed.
+- Drop unused base define.
+
+-------------------------------------------------------------------

Old:
----
  libdazzle-3.26.2.tar.xz

New:
----
  libdazzle-3.26.3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libdazzle.spec ++++++
--- /var/tmp/diff_new_pack.KeSs2R/_old  2018-02-03 15:39:28.429858874 +0100
+++ /var/tmp/diff_new_pack.KeSs2R/_new  2018-02-03 15:39:28.433858688 +0100
@@ -16,9 +16,8 @@
 #
 
 
-%define base 3.25
 Name:           libdazzle
-Version:        3.26.2
+Version:        3.26.3
 Release:        0
 Summary:        Collection of fancy features for GLib and Gtk+
 License:        GPL-3.0+ AND LGPL-2.1+

++++++ libdazzle-3.26.2.tar.xz -> libdazzle-3.26.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/NEWS new/libdazzle-3.26.3/NEWS
--- old/libdazzle-3.26.2/NEWS   2018-01-11 02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/NEWS   2018-02-01 00:00:27.000000000 +0100
@@ -1,4 +1,24 @@
 ==============
+Version 3.26.3
+==============
+
+Changes in this release:
+
+ • A number of fixes to DzlSignalGroup to be more re-entrant safe
+   and handle disposal cycles better.
+ • DzlPreferences is more aggressive about protecting against
+   widget disposal.
+ • A static inline dzl_clear_signal_handler() was backported for
+   use in other backports from master.
+ • A number of protections were added to DzlDirectoryReaper to
+   protect against potentially following through symlinks.
+ • Max age in DzlDirectoryReaper was changed to always ensure
+   a positive value for use in date comparisons.
+ • A leak of GFile instances in the directory reaper was fixed.
+
+It's recommended that all distributions update to this release.
+
+==============
 Version 3.26.2
 ==============
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/meson.build 
new/libdazzle-3.26.3/meson.build
--- old/libdazzle-3.26.2/meson.build    2018-01-11 02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/meson.build    2018-02-01 00:00:27.000000000 +0100
@@ -1,5 +1,5 @@
 project('libdazzle', 'c',
-          version: '3.26.2',
+          version: '3.26.3',
           license: 'GPLv3+',
     meson_version: '>= 0.40.1',
   default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 
'c_std=gnu11' ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/src/bindings/dzl-signal-group.c 
new/libdazzle-3.26.3/src/bindings/dzl-signal-group.c
--- old/libdazzle-3.26.2/src/bindings/dzl-signal-group.c        2018-01-11 
02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/src/bindings/dzl-signal-group.c        2018-02-01 
00:00:27.000000000 +0100
@@ -52,10 +52,12 @@
 {
   GObject     parent_instance;
 
-  GObject    *target;
+  GWeakRef    target_ref;
   GPtrArray  *handlers;
   GType       target_type;
   gsize       block_count;
+
+  guint       has_bound_at_least_once : 1;
 };
 
 struct _DzlSignalGroupClass
@@ -71,7 +73,6 @@
   DzlSignalGroup *group;
   gulong          handler_id;
   GClosure       *closure;
-  GObject        *object;
   guint           signal_id;
   GQuark          signal_detail;
   guint           connect_after : 1;
@@ -120,71 +121,64 @@
 }
 
 static void
-dzl_signal_group__target_weak_notify (gpointer  data,
-                                      GObject  *where_object_was)
+dzl_signal_group_gc_handlers (DzlSignalGroup *self)
 {
-  DzlSignalGroup *self = data;
-  gsize i;
-
   g_assert (DZL_IS_SIGNAL_GROUP (self));
-  g_assert (where_object_was != NULL);
-  g_assert (self->target == where_object_was);
 
-  for (i = 0; i < self->handlers->len; i++)
-    {
-      SignalHandler *handler;
+  /*
+   * Remove any handlers for which the closures have become invalid. We do
+   * this cleanup lazily to avoid situations where we could have disposal
+   * active on both the signal group and the peer object.
+   */
 
-      handler = g_ptr_array_index (self->handlers, i);
-      handler->handler_id = 0;
-    }
+  for (guint i = self->handlers->len; i > 0; i--)
+    {
+      const SignalHandler *handler = g_ptr_array_index (self->handlers, i - 1);
 
-  self->target = NULL;
+      g_assert (handler != NULL);
+      g_assert (handler->closure != NULL);
 
-  g_signal_emit (self, signals [UNBIND], 0);
-  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TARGET]);
+      if (handler->closure->is_invalid)
+        g_ptr_array_remove_index (self->handlers, i - 1);
+    }
 }
 
 static void
-dzl_signal_group__connect_object_weak_notify (gpointer  data,
-                                              GObject  *where_object_was)
+dzl_signal_group__target_weak_notify (gpointer  data,
+                                      GObject  *where_object_was)
 {
   DzlSignalGroup *self = data;
-  gsize i;
 
   g_assert (DZL_IS_SIGNAL_GROUP (self));
   g_assert (where_object_was != NULL);
 
-  for (i = 0; i < self->handlers->len; ++i)
-    {
-      SignalHandler *handler;
+  g_weak_ref_set (&self->target_ref, NULL);
 
-      handler = g_ptr_array_index (self->handlers, i);
+  for (guint i = 0; i < self->handlers->len; i++)
+    {
+      SignalHandler *handler = g_ptr_array_index (self->handlers, i);
 
-      if (handler->object == where_object_was)
-        {
-          handler->object = NULL;
-          g_ptr_array_remove_index_fast (self->handlers, i);
-          return;
-        }
+      handler->handler_id = 0;
     }
 
-  g_critical ("Failed to find handler for %p", (void *)where_object_was);
+  g_signal_emit (self, signals [UNBIND], 0);
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TARGET]);
 }
 
 static void
 dzl_signal_group_bind_handler (DzlSignalGroup *self,
-                               SignalHandler  *handler)
+                               SignalHandler  *handler,
+                               GObject        *target)
 {
-  gsize i;
-
   g_assert (self != NULL);
-  g_assert (self->target != NULL);
+  g_assert (G_IS_OBJECT (target));
   g_assert (handler != NULL);
   g_assert (handler->signal_id != 0);
   g_assert (handler->closure != NULL);
+  g_assert (handler->closure->is_invalid == 0);
   g_assert (handler->handler_id == 0);
 
-  handler->handler_id = g_signal_connect_closure_by_id (self->target,
+  handler->handler_id = g_signal_connect_closure_by_id (target,
                                                         handler->signal_id,
                                                         handler->signal_detail,
                                                         handler->closure,
@@ -192,63 +186,75 @@
 
   g_assert (handler->handler_id != 0);
 
-  for (i = 0; i < self->block_count; i++)
-    g_signal_handler_block (self->target, handler->handler_id);
+  for (guint i = 0; i < self->block_count; i++)
+    g_signal_handler_block (target, handler->handler_id);
 }
 
 static void
 dzl_signal_group_bind (DzlSignalGroup *self,
                        GObject        *target)
 {
-  gsize i;
+  g_autoptr(GObject) hold = NULL;
 
   g_assert (DZL_IS_SIGNAL_GROUP (self));
-  g_assert (self->target == NULL);
   g_assert (!target || G_IS_OBJECT (target));
 
   if (target == NULL)
     return;
 
-  self->target = target;
-  g_object_weak_ref (self->target,
-                     dzl_signal_group__target_weak_notify,
-                     self);
+  self->has_bound_at_least_once = TRUE;
+
+  hold = g_object_ref (target);
 
-  g_object_ref (target);
+  g_weak_ref_set (&self->target_ref, hold);
+  g_object_weak_ref (hold, dzl_signal_group__target_weak_notify, self);
 
-  for (i = 0; i < self->handlers->len; i++)
+  dzl_signal_group_gc_handlers (self);
+
+  for (guint i = 0; i < self->handlers->len; i++)
     {
-      SignalHandler *handler;
+      SignalHandler *handler = g_ptr_array_index (self->handlers, i);
 
-      handler = g_ptr_array_index (self->handlers, i);
-      dzl_signal_group_bind_handler (self, handler);
+      dzl_signal_group_bind_handler (self, handler, hold);
     }
 
-  g_signal_emit (self, signals [BIND], 0, target);
-  g_object_unref (target);
+  g_signal_emit (self, signals [BIND], 0, hold);
 }
 
 static void
 dzl_signal_group_unbind (DzlSignalGroup *self)
 {
-  GObject *target;
-  gsize i;
+  g_autoptr(GObject) target = NULL;
 
   g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
 
-  if (self->target == NULL)
-    return;
+  target = g_weak_ref_get (&self->target_ref);
 
-  target = self->target;
-  self->target = NULL;
+  /*
+   * Target may be NULL by this point, as we got notified of its destruction.
+   * However, if we're early enough, we may get a full reference back and can
+   * cleanly disconnect our connections.
+   */
+
+  if (target != NULL)
+    {
+      g_weak_ref_set (&self->target_ref, NULL);
+
+      /*
+       * Let go of our weak reference now that we have a full reference
+       * for the life of this function.
+       */
+      g_object_weak_unref (target,
+                           dzl_signal_group__target_weak_notify,
+                           self);
+    }
 
-  g_object_weak_unref (target,
-                       dzl_signal_group__target_weak_notify,
-                       self);
+  dzl_signal_group_gc_handlers (self);
 
-  for (i = 0; i < self->handlers->len; i++)
+  for (guint i = 0; i < self->handlers->len; i++)
     {
       SignalHandler *handler;
+      gulong handler_id;
 
       handler = g_ptr_array_index (self->handlers, i);
 
@@ -256,15 +262,17 @@
       g_assert (handler->signal_id != 0);
       g_assert (handler->closure != NULL);
 
-      if (handler->handler_id != 0)
-        {
-          gulong handler_id;
+      handler_id = handler->handler_id;
+      handler->handler_id = 0;
 
-          handler_id = handler->handler_id;
-          handler->handler_id = 0;
+      /*
+       * If @target is NULL, we lost a race to cleanup the weak
+       * instance and the signal connections have already been
+       * finalized and therefore nothing to do.
+       */
 
-          g_signal_handler_disconnect (target, handler_id);
-        }
+      if (target != NULL && handler_id != 0)
+        g_signal_handler_disconnect (target, handler_id);
     }
 
   g_signal_emit (self, signals [UNBIND], 0);
@@ -302,28 +310,28 @@
 void
 dzl_signal_group_block (DzlSignalGroup *self)
 {
-  gsize i;
+  g_autoptr(GObject) target = NULL;
 
   g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
   g_return_if_fail (self->block_count != G_MAXSIZE);
 
   self->block_count++;
 
-  if (self->target == NULL)
+  target = g_weak_ref_get (&self->target_ref);
+
+  if (target == NULL)
     return;
 
-  for (i = 0; i < self->handlers->len; i++)
+  for (guint i = 0; i < self->handlers->len; i++)
     {
-      SignalHandler *handler;
-
-      handler = g_ptr_array_index (self->handlers, i);
+      const SignalHandler *handler = g_ptr_array_index (self->handlers, i);
 
       g_assert (handler != NULL);
       g_assert (handler->signal_id != 0);
       g_assert (handler->closure != NULL);
       g_assert (handler->handler_id != 0);
 
-      g_signal_handler_block (self->target, handler->handler_id);
+      g_signal_handler_block (target, handler->handler_id);
     }
 }
 
@@ -341,28 +349,28 @@
 void
 dzl_signal_group_unblock (DzlSignalGroup *self)
 {
-  gsize i;
+  g_autoptr(GObject) target = NULL;
 
   g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
   g_return_if_fail (self->block_count != 0);
 
   self->block_count--;
 
-  if (self->target == NULL)
+  target = g_weak_ref_get (&self->target_ref);
+
+  if (target == NULL)
     return;
 
-  for (i = 0; i < self->handlers->len; i++)
+  for (guint i = 0; i < self->handlers->len; i++)
     {
-      SignalHandler *handler;
-
-      handler = g_ptr_array_index (self->handlers, i);
+      const SignalHandler *handler = g_ptr_array_index (self->handlers, i);
 
       g_assert (handler != NULL);
       g_assert (handler->signal_id != 0);
       g_assert (handler->closure != NULL);
       g_assert (handler->handler_id != 0);
 
-      g_signal_handler_unblock (self->target, handler->handler_id);
+      g_signal_handler_unblock (target, handler->handler_id);
     }
 }
 
@@ -377,9 +385,27 @@
 gpointer
 dzl_signal_group_get_target (DzlSignalGroup *self)
 {
+  g_autoptr(GObject) target = NULL;
+
   g_return_val_if_fail (DZL_IS_SIGNAL_GROUP (self), NULL);
 
-  return (gpointer)self->target;
+  target = g_weak_ref_get (&self->target_ref);
+
+  /*
+   * It is expected that this is called from a thread that owns a reference to
+   * the target, so we can pass back a borrowed reference. However, to ensure
+   * that we aren't racing in finalization of @target, we must ensure that the
+   * ref_count >= 2 (as our get just incremented by one).
+   */
+
+  if (target == NULL || target->ref_count < 2)
+    return NULL;
+
+  /* Unref and pass back a borrowed reference. This looks unsafe, but is safe
+   * because of our reference check above, so much as the assertion holds that
+   * the caller obeyed the ownership rules of this class.
+   */
+  return target;
 }
 
 /**
@@ -399,16 +425,24 @@
 dzl_signal_group_set_target (DzlSignalGroup *self,
                              gpointer        target)
 {
+  g_autoptr(GObject) object = NULL;
+
   g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
 
-  if (target == (gpointer)self->target)
+  object = g_weak_ref_get (&self->target_ref);
+
+  if (object == (GObject *)target)
     return;
 
   if (!dzl_signal_group_check_target_type (self, target))
     return;
 
-  dzl_signal_group_unbind (self);
+  /* Only emit unbind if we've ever called bind */
+  if (self->has_bound_at_least_once)
+    dzl_signal_group_unbind (self);
+
   dzl_signal_group_bind (self, target);
+
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TARGET]);
 }
 
@@ -417,18 +451,13 @@
 {
   SignalHandler *handler = data;
 
-  if (handler->object != NULL)
-    {
-      g_object_weak_unref (handler->object,
-                           dzl_signal_group__connect_object_weak_notify,
-                           handler->group);
-      handler->object = NULL;
-    }
+  if (handler->closure != NULL)
+    g_closure_invalidate (handler->closure);
 
-  g_clear_pointer (&handler->closure, g_closure_unref);
   handler->handler_id = 0;
   handler->signal_id = 0;
   handler->signal_detail = 0;
+  g_clear_pointer (&handler->closure, g_closure_unref);
   g_slice_free (SignalHandler, handler);
 }
 
@@ -436,8 +465,9 @@
 dzl_signal_group_constructed (GObject *object)
 {
   DzlSignalGroup *self = (DzlSignalGroup *)object;
+  g_autoptr(GObject) target = g_weak_ref_get (&self->target_ref);
 
-  if (!dzl_signal_group_check_target_type (self, self->target))
+  if (!dzl_signal_group_check_target_type (self, target))
     dzl_signal_group_set_target (self, NULL);
 
   G_OBJECT_CLASS (dzl_signal_group_parent_class)->constructed (object);
@@ -448,13 +478,27 @@
 {
   DzlSignalGroup *self = (DzlSignalGroup *)object;
 
-  dzl_signal_group_unbind (self);
+  dzl_signal_group_gc_handlers (self);
+
+  if (self->has_bound_at_least_once)
+    dzl_signal_group_unbind (self);
+
   g_clear_pointer (&self->handlers, g_ptr_array_unref);
 
   G_OBJECT_CLASS (dzl_signal_group_parent_class)->dispose (object);
 }
 
 static void
+dzl_signal_group_finalize (GObject *object)
+{
+  DzlSignalGroup *self = (DzlSignalGroup *)object;
+
+  g_weak_ref_clear (&self->target_ref);
+
+  G_OBJECT_CLASS (dzl_signal_group_parent_class)->finalize (object);
+}
+
+static void
 dzl_signal_group_get_property (GObject    *object,
                                guint       prop_id,
                                GValue     *value,
@@ -465,7 +509,7 @@
   switch (prop_id)
     {
     case PROP_TARGET:
-      g_value_set_object (value, dzl_signal_group_get_target (self));
+      g_value_take_object (value, g_weak_ref_get (&self->target_ref));
       break;
 
     case PROP_TARGET_TYPE:
@@ -507,6 +551,7 @@
 
   object_class->constructed = dzl_signal_group_constructed;
   object_class->dispose = dzl_signal_group_dispose;
+  object_class->finalize = dzl_signal_group_finalize;
   object_class->get_property = dzl_signal_group_get_property;
   object_class->set_property = dzl_signal_group_set_property;
 
@@ -520,7 +565,7 @@
                          "Target",
                          "The target instance used when connecting signals.",
                          G_TYPE_OBJECT,
-                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS));
 
   /**
    * DzlSignalGroup:target-type
@@ -610,6 +655,7 @@
                                GConnectFlags   flags,
                                gboolean        is_object)
 {
+  g_autoptr(GObject) target = NULL;
   SignalHandler *handler;
   GClosure *closure;
   guint signal_id;
@@ -620,6 +666,7 @@
   g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
                                          &signal_id, &signal_detail, TRUE) != 
0);
   g_return_if_fail (callback != NULL);
+  g_return_if_fail (!is_object || G_IS_OBJECT (data));
 
   if ((flags & G_CONNECT_SWAPPED) != 0)
     closure = g_cclosure_new_swap (callback, data, notify);
@@ -637,19 +684,21 @@
 
   if (is_object)
     {
-      /* This is what g_cclosure_new_object() does */
+      /* Set closure->is_invalid when data is disposed. We only track this to 
avoid
+       * reconnecting in the future. However, we do a round of cleanup when 
ever we
+       * connect a new object or the target changes to GC the old handlers.
+       */
       g_object_watch_closure (data, closure);
-
-      handler->object = data;
-      g_object_weak_ref (data,
-                         dzl_signal_group__connect_object_weak_notify,
-                         self);
     }
 
   g_ptr_array_add (self->handlers, handler);
 
-  if (self->target != NULL)
-    dzl_signal_group_bind_handler (self, handler);
+  target = g_weak_ref_get (&self->target_ref);
+  if (target != NULL)
+    dzl_signal_group_bind_handler (self, handler, target);
+
+  /* Lazily remove any old handlers on connect */
+  dzl_signal_group_gc_handlers (self);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/src/files/dzl-directory-reaper.c 
new/libdazzle-3.26.3/src/files/dzl-directory-reaper.c
--- old/libdazzle-3.26.2/src/files/dzl-directory-reaper.c       2018-01-11 
02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/src/files/dzl-directory-reaper.c       2018-02-01 
00:00:27.000000000 +0100
@@ -121,7 +121,7 @@
     glob = "*";
 
   p.type = PATTERN_GLOB;
-  p.min_age = min_age;
+  p.min_age = ABS (min_age);
   p.glob.directory = g_object_ref (directory);
   p.glob.glob = g_strdup (glob);
 
@@ -139,7 +139,7 @@
   g_return_if_fail (G_IS_FILE (file));
 
   p.type = PATTERN_FILE;
-  p.min_age = min_age;
+  p.min_age = ABS (min_age);
   p.file.file = g_object_ref (file);
 
   g_array_append_val (self->patterns, p);
@@ -168,6 +168,7 @@
   g_debug ("Removing uri recursively \"%s\"", uri);
 
   enumerator = g_file_enumerate_children (file,
+                                          
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","
                                           G_FILE_ATTRIBUTE_STANDARD_NAME","
                                           G_FILE_ATTRIBUTE_STANDARD_TYPE","
                                           G_FILE_ATTRIBUTE_TIME_MODIFIED,
@@ -189,10 +190,10 @@
   while (NULL != (infoptr = g_file_enumerator_next_file (enumerator, 
cancellable, &enum_error)))
     {
       g_autoptr(GFileInfo) info = infoptr;
-      const gchar *name = g_file_info_get_name (info);
-      GFile *child = g_file_get_child (file, name);
+      g_autoptr(GFile) child = g_file_enumerator_get_child (enumerator, info);
+      GFileType file_type = g_file_info_get_file_type (info);
 
-      if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+      if (!g_file_info_get_is_symlink (info) && file_type == 
G_FILE_TYPE_DIRECTORY)
         {
           if (!remove_directory_with_children (child, cancellable, error))
             return FALSE;
@@ -278,7 +279,9 @@
             }
 
           enumerator = g_file_enumerate_children (p->glob.directory,
+                                                  
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","
                                                   
G_FILE_ATTRIBUTE_STANDARD_NAME","
+                                                  
G_FILE_ATTRIBUTE_STANDARD_TYPE","
                                                   
G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                                   
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                                   cancellable,
@@ -293,9 +296,6 @@
 
           while (NULL != (info = g_file_enumerator_next_file (enumerator, 
cancellable, NULL)))
             {
-              const gchar *name;
-
-              name = g_file_info_get_name (info);
               v64 = g_file_info_get_attribute_uint64 (info, 
G_FILE_ATTRIBUTE_TIME_MODIFIED);
 
               /* mtime is in seconds */
@@ -303,21 +303,27 @@
 
               if (v64 < now - p->min_age)
                 {
-                  g_autoptr(GFile) file = g_file_get_child (p->glob.directory, 
name);
+                  g_autoptr(GFile) file = g_file_enumerator_get_child 
(enumerator, info);
+                  GFileType file_type = g_file_info_get_file_type (info);
 
-                  if (g_file_query_file_type (file, 
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable) == G_FILE_TYPE_DIRECTORY)
+                  if (g_file_info_get_is_symlink (info) || file_type != 
G_FILE_TYPE_DIRECTORY)
                     {
-                      if (!remove_directory_with_children (file, cancellable, 
&error) ||
-                          !g_file_delete (file, cancellable, &error))
+                      if (!g_file_delete (file, cancellable, &error))
                         {
                           g_warning ("%s", error->message);
                           g_clear_error (&error);
                         }
                     }
-                  else if (!g_file_delete (file, cancellable, &error))
+                  else
                     {
-                      g_warning ("%s", error->message);
-                      g_clear_error (&error);
+                      g_assert (file_type == G_FILE_TYPE_DIRECTORY);
+
+                      if (!remove_directory_with_children (file, cancellable, 
&error) ||
+                          !g_file_delete (file, cancellable, &error))
+                        {
+                          g_warning ("%s", error->message);
+                          g_clear_error (&error);
+                        }
                     }
                 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/src/prefs/dzl-preferences-view.c 
new/libdazzle-3.26.3/src/prefs/dzl-preferences-view.c
--- old/libdazzle-3.26.2/src/prefs/dzl-preferences-view.c       2018-01-11 
02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/src/prefs/dzl-preferences-view.c       2018-02-01 
00:00:27.000000000 +0100
@@ -63,10 +63,19 @@
   TrackedWidget *tracked = data;
 
   if (tracked->widget != NULL)
-    g_signal_handler_disconnect (tracked->widget, tracked->handler);
+    {
+      dzl_clear_signal_handler (tracked->widget, &tracked->handler);
+      tracked->widget = NULL;
+    }
+
+  tracked->handler = 0;
+  tracked->id = 0;
+
   g_slice_free (TrackedWidget, tracked);
 }
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (TrackedWidget, tracked_widget_free)
+
 static void
 dzl_preferences_view_track (DzlPreferencesView *self,
                             guint               id,
@@ -849,10 +858,10 @@
 {
   DzlPreferencesView *self = (DzlPreferencesView *)preferences;
   DzlPreferencesViewPrivate *priv = dzl_preferences_view_get_instance_private 
(self);
-  TrackedWidget *tracked;
+  g_autoptr(TrackedWidget) tracked = NULL;
 
   g_assert (DZL_IS_PREFERENCES_VIEW (self));
-  g_assert (widget_id);
+  g_assert (widget_id != 0);
 
   tracked = g_hash_table_lookup (priv->widgets, GUINT_TO_POINTER (widget_id));
 
@@ -860,7 +869,10 @@
     {
       GtkWidget *widget = tracked->widget;
 
-      g_hash_table_remove (priv->widgets, GUINT_TO_POINTER (widget_id));
+      /* We have to steal the structure so that we retain access to
+       * the structure after removing it from the hashtable.
+       */
+      g_hash_table_steal (priv->widgets, GUINT_TO_POINTER (widget_id));
 
       if (widget != NULL && !gtk_widget_in_destruction (widget))
         {
@@ -871,9 +883,9 @@
             gtk_widget_destroy (parent);
           else
             gtk_widget_destroy (widget);
-
-          return TRUE;
         }
+
+      return TRUE;
     }
 
   return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/src/util/dzl-macros.h 
new/libdazzle-3.26.3/src/util/dzl-macros.h
--- old/libdazzle-3.26.2/src/util/dzl-macros.h  2018-01-11 02:10:36.000000000 
+0100
+++ new/libdazzle-3.26.3/src/util/dzl-macros.h  2018-02-01 00:00:27.000000000 
+0100
@@ -37,6 +37,18 @@
 #define dzl_set_weak_pointer(ptr,obj) \
   
((obj!=*(ptr))?(dzl_clear_weak_pointer(ptr),*(ptr)=obj,((obj)?g_object_add_weak_pointer((GObject*)obj,(gpointer*)ptr),NULL:NULL),1):0)
 
+static inline void
+dzl_clear_signal_handler (gpointer  object,
+                          gulong   *location_of_handler)
+{
+  if (*location_of_handler != 0)
+    {
+      gulong handler = *location_of_handler;
+      *location_of_handler = 0;
+      g_signal_handler_disconnect (object, handler);
+    }
+}
+
 static inline gboolean
 dzl_str_empty0 (const gchar *str)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdazzle-3.26.2/tests/test-directory-reaper.c 
new/libdazzle-3.26.3/tests/test-directory-reaper.c
--- old/libdazzle-3.26.2/tests/test-directory-reaper.c  2018-01-11 
02:10:36.000000000 +0100
+++ new/libdazzle-3.26.3/tests/test-directory-reaper.c  2018-02-01 
00:00:27.000000000 +0100
@@ -69,6 +69,15 @@
       g_assert_cmpint (r, ==, TRUE);
     }
 
+  /* Add a symlink to ../ so that we keep ourselves honest ;) */
+  {
+    g_autofree gchar *cwd = g_get_current_dir ();
+    g_autofree gchar *name = g_build_filename ("reaper", "parent-link", NULL);
+
+    if (symlink (cwd, name) != 0)
+      g_error ("Failed to create symlink");
+  }
+
   dzl_directory_reaper_add_directory (reaper, file, 0);
 
   r = dzl_directory_reaper_execute (reaper, NULL, &error);


Reply via email to