[gtk+] cssnode: Move clear_classes() into the NodeDeclaration



commit 610452dda87e4142114448cef99956fcda93ca2b
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 12 02:58:28 2015 +0200

    cssnode: Move clear_classes() into the NodeDeclaration
    
    The previous code was crashing when used as the returned classes array
    would have been invalid after the first deletion. So if a 2nd class
    would be deleted, invalid memory might have been referenced.

 gtk/gtkcssnode.c                   |   10 +++-------
 gtk/gtkcssnodedeclaration.c        |   15 +++++++++++++++
 gtk/gtkcssnodedeclarationprivate.h |    1 +
 3 files changed, 19 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 9b5db15..4d2563d 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -1054,14 +1054,10 @@ gtk_css_node_get_junction_sides (GtkCssNode *cssnode)
 static void
 gtk_css_node_clear_classes (GtkCssNode *cssnode)
 {
-  const GQuark *classes;
-  guint n_classes, i;
-
-  classes = gtk_css_node_declaration_get_classes (cssnode->decl, &n_classes);
-
-  for (i = 0; i < n_classes; ++i)
+  if (gtk_css_node_declaration_clear_classes (&cssnode->decl))
     {
-      gtk_css_node_remove_class (cssnode, classes[i]);
+      gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
+      g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_CLASSES]);
     }
 }
 
diff --git a/gtk/gtkcssnodedeclaration.c b/gtk/gtkcssnodedeclaration.c
index c16189b..8e425a4 100644
--- a/gtk/gtkcssnodedeclaration.c
+++ b/gtk/gtkcssnodedeclaration.c
@@ -308,6 +308,21 @@ gtk_css_node_declaration_remove_class (GtkCssNodeDeclaration **decl,
 }
 
 gboolean
+gtk_css_node_declaration_clear_classes (GtkCssNodeDeclaration **decl)
+{
+  if ((*decl)->n_classes == 0)
+    return FALSE;
+
+  gtk_css_node_declaration_make_writable_resize (decl,
+                                                 (char *) get_classes (*decl) - (char *) *decl,
+                                                 0,
+                                                 sizeof (GQuark) * (*decl)->n_classes);
+  (*decl)->n_classes = 0;
+
+  return TRUE;
+}
+
+gboolean
 gtk_css_node_declaration_has_class (const GtkCssNodeDeclaration *decl,
                                     GQuark                       class_quark)
 {
diff --git a/gtk/gtkcssnodedeclarationprivate.h b/gtk/gtkcssnodedeclarationprivate.h
index 51c8c62..f1499b2 100644
--- a/gtk/gtkcssnodedeclarationprivate.h
+++ b/gtk/gtkcssnodedeclarationprivate.h
@@ -45,6 +45,7 @@ gboolean                gtk_css_node_declaration_add_class              (GtkCssN
                                                                          GQuark                         
class_quark);
 gboolean                gtk_css_node_declaration_remove_class           (GtkCssNodeDeclaration        **decl,
                                                                          GQuark                         
class_quark);
+gboolean                gtk_css_node_declaration_clear_classes          (GtkCssNodeDeclaration        
**decl);
 gboolean                gtk_css_node_declaration_has_class              (const GtkCssNodeDeclaration   *decl,
                                                                          GQuark                         
class_quark);
 const GQuark *          gtk_css_node_declaration_get_classes            (const GtkCssNodeDeclaration   *decl,


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