[glade3] * gladeui/glade-project.c, gladeui/glade-id-allocator.c: Dont index unallocated memory when rele



commit b1605958ed7ec3058f0d9386c5e899f70a002447
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Mon Jan 3 23:57:18 2011 +0900

    	* gladeui/glade-project.c, gladeui/glade-id-allocator.c: Dont index unallocated
    	  memory when releasing a widget name that was never allocated (this can happen
    	  for loaded widgets with a number), fixes crash when setting naming policy for
    	  glom_developer.glade.

 ChangeLog                    |    4 ++++
 gladeui/glade-id-allocator.c |   19 ++++++++++++++++---
 gladeui/glade-name-context.c |   35 ++++++++++++++++++++++++-----------
 gladeui/glade-project.c      |   13 +++----------
 4 files changed, 47 insertions(+), 24 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 37436f5..a909e44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,10 @@
 
 	19 files changed, 652 insertions(+), 1135 deletions(-)
 
+	* gladeui/glade-project.c, gladeui/glade-id-allocator.c: Dont index unallocated
+	  memory when releasing a widget name that was never allocated (this can happen
+	  for loaded widgets with a number), fixes crash when setting naming policy for
+	  glom_developer.glade.
 
 2011-01-02  Tristan Van Berkom <tristanvb openismus com>
 
diff --git a/gladeui/glade-id-allocator.c b/gladeui/glade-id-allocator.c
index b125e89..884b22d 100644
--- a/gladeui/glade-id-allocator.c
+++ b/gladeui/glade-id-allocator.c
@@ -47,7 +47,7 @@ glade_id_allocator_new (void)
   GladeIDAllocator *allocator = g_slice_new (GladeIDAllocator);
 
   allocator->n_words = INITIAL_WORDS;
-  allocator->data = g_new (guint32, INITIAL_WORDS);
+  allocator->data    = g_new (guint32, INITIAL_WORDS);
 
   memset (allocator->data, 0xff, INITIAL_WORDS * sizeof (guint32));
 
@@ -150,10 +150,23 @@ glade_id_allocator_allocate (GladeIDAllocator * allocator)
 void
 glade_id_allocator_release (GladeIDAllocator * allocator, guint id)
 {
+  guint word_idx;
+
   g_return_if_fail (allocator != NULL);
 
-  id = id > 0 ? id - 1 : 0;
-  allocator->data[id >> 5] |= 1 << (id & 31);
+  /* Allocated ids start with 1 */
+  if (id > 0)
+    {
+      id = id - 1;
+      word_idx = id >> 5;
+
+      /* Tollerate releasing ids that were never allocated with the allocator 
+       * or are out of range... when we load Glade files with huge numbers it happens
+       * that loaded unallocated ids are out of range
+       */
+      if (word_idx < allocator->n_words)
+	allocator->data[word_idx] |= 1 << (id & 31);
+    }
 }
 
 #ifdef GLADE_ID_ALLOCATOR_TEST
diff --git a/gladeui/glade-name-context.c b/gladeui/glade-name-context.c
index ca8d47b..e94e250 100644
--- a/gladeui/glade-name-context.c
+++ b/gladeui/glade-name-context.c
@@ -43,7 +43,7 @@ struct _GladeNameContext
 GladeNameContext *
 glade_name_context_new (void)
 {
-  GladeNameContext *context = g_new0 (GladeNameContext, 1);
+  GladeNameContext *context = g_slice_new0 (GladeNameContext);
 
   context->name_allocators = g_hash_table_new_full (g_str_hash,
                                                     g_str_equal,
@@ -64,7 +64,7 @@ glade_name_context_destroy (GladeNameContext * context)
 
   g_hash_table_destroy (context->name_allocators);
   g_hash_table_destroy (context->names);
-  g_free (context);
+  g_slice_free (GladeNameContext, context);
 }
 
 gchar *
@@ -116,9 +116,11 @@ glade_name_context_dual_new_name (GladeNameContext * context,
                                   const gchar * base_name)
 {
   GladeIDAllocator *id_allocator;
-  const gchar *number;
-  gchar *name = NULL, *freeme = NULL;
-  guint i = 1;
+  GList            *free_ids = NULL, *l;
+  const gchar      *number;
+  gchar            *name = NULL, *freeme = NULL;
+  guint             i;
+  gboolean          found = FALSE;
 
   g_return_val_if_fail (context != NULL, NULL);
   g_return_val_if_fail (another_context != NULL, NULL);
@@ -143,14 +145,27 @@ glade_name_context_dual_new_name (GladeNameContext * context,
                            g_strdup (base_name), id_allocator);
     }
 
-  do
+  while (!found)
     {
       g_free (name);
       i = glade_id_allocator_allocate (id_allocator);
       name = g_strdup_printf ("%s%u", base_name, i);
+
+      if (!(glade_name_context_has_name (context, name) ||
+	    glade_name_context_has_name (another_context, name)))
+	found = TRUE;
+      else
+	free_ids = g_list_prepend (free_ids, GUINT_TO_POINTER (i));
     }
-  while (glade_name_context_has_name (context, name) ||
-         glade_name_context_has_name (another_context, name));
+
+  /* Release all the ids that were not hits */
+  for (l = free_ids; l; l = l->next)
+    {
+      i = GPOINTER_TO_UINT (l->data);
+      
+      glade_id_allocator_release (id_allocator, i);
+    }
+  g_list_free (free_ids);
 
   g_free (freeme);
   return name;
@@ -222,17 +237,15 @@ glade_name_context_release_name (GladeNameContext * context, const gchar * name)
   if (ch == 0)
     return;
 
-
   base_name = g_strdup (name);
   *(base_name + (first_number - name)) = 0;
 
   if ((id_allocator =
        g_hash_table_lookup (context->name_allocators, base_name)) != NULL)
     {
-
       id = (int) strtol (first_number, &end_number, 10);
       if (*end_number == 0)
-        glade_id_allocator_release (id_allocator, id);
+	glade_id_allocator_release (id_allocator, id);
     }
 
   g_free (base_name);
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 0ba09ef..c0bcac8 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -110,8 +110,7 @@ struct _GladeProjectPrivate
   gboolean has_selection;       /* Whether the project has a selection */
 
   GladeNameContext *toplevel_names;     /* Context for uniqueness of names at the toplevel */
-  GList *toplevels;             /* List of toplevels with thier own naming contexts */
-
+  GList *toplevels;                     /* List of toplevels with thier own naming contexts */
 
 
   GList *undo_stack;            /* A stack with the last executed commands */
@@ -164,7 +163,7 @@ struct _GladeProjectPrivate
 
 typedef struct
 {
-  GladeWidget *toplevel;
+  GladeWidget      *toplevel;
   GladeNameContext *names;
 } TopLevelInfo;
 
@@ -2616,7 +2615,6 @@ glade_project_release_widget_name (GladeProject * project,
           g_list_remove (project->priv->toplevels, tinfo);
       g_free (tinfo);
     }
-
 }
 
 /**
@@ -2659,8 +2657,6 @@ glade_project_available_widget_name (GladeProject * project,
     available =
         !glade_name_context_has_name (project->priv->toplevel_names, name);
 
-  //g_print ("widget name %s is available: %d (policy %d)\n", name, available, project->priv->naming_policy);
-
   return available;
 }
 
@@ -2731,8 +2727,6 @@ glade_project_new_widget_name (GladeProject * project,
     name =
         glade_name_context_new_name (project->priv->toplevel_names, base_name);
 
-  //g_print ("Allocating widget name %s, widget parent %p\n", name, widget->parent);
-
   return name;
 }
 
@@ -4069,8 +4063,7 @@ glade_project_build_prefs_box (GladeProject * project)
       gtk_radio_button_new_with_label (NULL, _("within the project"));
   project->priv->toplevel_contextual_radio =
       gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON
-                                                   (project->priv->
-                                                    project_wide_radio),
+                                                   (project->priv->project_wide_radio),
                                                    _("inside toplevels"));
 
   gtk_size_group_add_widget (sizegroup1, project->priv->project_wide_radio);



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