From 610452dda87e4142114448cef99956fcda93ca2b Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 12 Sep 2015 02:58:28 +0200 Subject: [PATCH] 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 9b5db15ad6..4d2563d7ab 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 c16189b1fe..8e425a4387 100644 --- a/gtk/gtkcssnodedeclaration.c +++ b/gtk/gtkcssnodedeclaration.c @@ -307,6 +307,21 @@ gtk_css_node_declaration_remove_class (GtkCssNodeDeclaration **decl, return TRUE; } +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 51c8c62b1f..f1499b2a67 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,