[gtk+] cssshadowsvalue: handle gtk_css_value_transition returning NULL



commit a021b72c717b41a03e21487e97dfa37a57222894
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Oct 16 14:22:24 2012 -0400

    cssshadowsvalue: handle gtk_css_value_transition returning NULL
    
    The implementation of transition for GtkCssShadowValue can return NULL
    at least when the two values have a different inset; all other parts of
    the GTK/CSS machinery (e.g. GtkCssArrayValue) handle this by returning
    NULL too. Instead, GtkCssShadowsValue was returning an invalid value,
    where "len" was set, but some values in the array were NULL, which would
    lead to a segfault when this value is later evaluated by the compute
    function.
    
    Fix this by making GtkCssShadowsValue return NULL if a shadow transition
    fails, like GtkCssArrayValue does.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686013

 gtk/gtkcssshadowsvalue.c |   42 ++++++++++++++++++++++++++++++++----------
 1 files changed, 32 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index 267c41c..0438316 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -98,42 +98,64 @@ gtk_css_value_shadows_transition (GtkCssValue *start,
                                   guint        property_id,
                                   double       progress)
 {
-  GtkCssValue *result;
-  guint i;
+  guint i, len;
+  GtkCssValue **values;
 
   /* catches the important case of 2 none values */
   if (start == end)
     return _gtk_css_value_ref (start);
 
   if (start->len > end->len)
-    result = gtk_css_shadows_value_new (start->values, start->len);
+    len = start->len;
   else
-    result = gtk_css_shadows_value_new (end->values, end->len);
+    len = end->len;
+
+  values = g_newa (GtkCssValue *, len);
 
   for (i = 0; i < MIN (start->len, end->len); i++)
     {
-      result->values[i] = _gtk_css_value_transition (start->values[i], end->values[i], property_id, progress);
+      values[i] = _gtk_css_value_transition (start->values[i], end->values[i], property_id, progress);
+      if (values[i] == NULL)
+        {
+          while (i--)
+            _gtk_css_value_unref (values[i]);
+          return NULL;
+        }
     }
   if (start->len > end->len)
     {
-      for (; i < result->len; i++)
+      for (; i < len; i++)
         {
           GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (start->values[i]);
-          result->values[i] = _gtk_css_value_transition (start->values[i], fill, property_id, progress);
+          values[i] = _gtk_css_value_transition (start->values[i], fill, property_id, progress);
           _gtk_css_value_unref (fill);
+
+          if (values[i] == NULL)
+            {
+              while (i--)
+                _gtk_css_value_unref (values[i]);
+              return NULL;
+            }
         }
     }
   else
     {
-      for (; i < result->len; i++)
+      for (; i < len; i++)
         {
           GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (end->values[i]);
-          result->values[i] = _gtk_css_value_transition (fill, end->values[i], property_id, progress);
+          values[i] = _gtk_css_value_transition (fill, end->values[i], property_id, progress);
           _gtk_css_value_unref (fill);
+
+          if (values[i] == NULL)
+            {
+              while (i--)
+                _gtk_css_value_unref (values[i]);
+              return NULL;
+            }
         }
     }
 
-  return result;
+  return gtk_css_shadows_value_new (values, len);
 }
 
 static void



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