[glib/glib-2-72: 11/39] gobject: Sink floating pspecs if adding them to a class fails




commit cd657d692d24289dd8c32dc036400cdccebde4ce
Author: Philip Withnall <pwithnall endlessos org>
Date:   Tue Jun 7 11:19:06 2022 +0100

    gobject: Sink floating pspecs if adding them to a class fails
    
    This may fix Coverity assuming that pspecs are leaked, which is causing
    tens and tens of false positives in the latest Coverity reports for
    GLib.
    
    Ensure that the pspecs are sunk (if floating) even if adding them to the
    class fails (due to validation failure or an identically named property
    already existing).
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    (cherry-picked from commit 8f7df344b636d5fda3d05560f5142d5d8515662a)

 gobject/gobject.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index d33d8e5b04..c33ee35809 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -572,22 +572,25 @@ g_object_do_class_init (GObjectClass *class)
   g_type_add_interface_check (NULL, object_interface_check_properties);
 }
 
+/* Sinks @pspec if it’s a floating ref. */
 static inline gboolean
 install_property_internal (GType       g_type,
                           guint       property_id,
                           GParamSpec *pspec)
 {
+  g_param_spec_ref_sink (pspec);
+
   if (g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type, FALSE))
     {
       g_warning ("When installing property: type '%s' already has a property named '%s'",
                 g_type_name (g_type),
                 pspec->name);
+      g_param_spec_unref (pspec);
       return FALSE;
     }
 
-  g_param_spec_ref_sink (pspec);
   PARAM_SPEC_SET_PARAM_ID (pspec, property_id);
-  g_param_spec_pool_insert (pspec_pool, pspec, g_type);
+  g_param_spec_pool_insert (pspec_pool, g_steal_pointer (&pspec), g_type);
   return TRUE;
 }
 
@@ -608,6 +611,7 @@ validate_pspec_to_install (GParamSpec *pspec)
   return TRUE;
 }
 
+/* Sinks @pspec if it’s a floating ref. */
 static gboolean
 validate_and_install_class_property (GObjectClass *class,
                                      GType         oclass_type,
@@ -616,7 +620,11 @@ validate_and_install_class_property (GObjectClass *class,
                                      GParamSpec   *pspec)
 {
   if (!validate_pspec_to_install (pspec))
-    return FALSE;
+    {
+      g_param_spec_ref_sink (pspec);
+      g_param_spec_unref (pspec);
+      return FALSE;
+    }
 
   if (pspec->flags & G_PARAM_WRITABLE)
     g_return_val_if_fail (class->set_property != NULL, FALSE);
@@ -824,7 +832,11 @@ g_object_interface_install_property (gpointer      g_iface,
   g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec)); /* paranoid */
 
   if (!validate_pspec_to_install (pspec))
-    return;
+    {
+      g_param_spec_ref_sink (pspec);
+      g_param_spec_unref (pspec);
+      return;
+    }
 
   (void) install_property_internal (iface_class->g_type, 0, pspec);
 }


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