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



commit 52e604e57907a22828b65a0c5394a17c8128bcab
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Tue Jan 4 00:15:42 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.
    
    Conflicts:
    
    	ChangeLog
    	gladeui/glade-id-allocator.c
    	gladeui/glade-name-context.c
    	gladeui/glade-project.c

 ChangeLog                    |    7 ++++++
 gladeui/glade-id-allocator.c |   17 +++++++++++++-
 gladeui/glade-name-context.c |   46 +++++++++++++++++++++++++----------------
 gladeui/glade-project.c      |    1 -
 4 files changed, 50 insertions(+), 21 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4378e2d..aaad364 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-01-03  Tristan Van Berkom <tristanvb openismus com>
+
+	* 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.
+
 2010-12-31  Tristan Van Berkom <tristanvb openismus com>
 
 	* gladeui/glade-project.c: Further fixing project dispose cycle, still leaking a little
diff --git a/gladeui/glade-id-allocator.c b/gladeui/glade-id-allocator.c
index b208cd4..2c4cec1 100644
--- a/gladeui/glade-id-allocator.c
+++ b/gladeui/glade-id-allocator.c
@@ -152,10 +152,23 @@ 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 42b1cc8..b39242e 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,
@@ -65,7 +65,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 *
@@ -117,10 +117,12 @@ glade_name_context_dual_new_name (GladeNameContext *context,
 				  const gchar      *base_name)
 {
 	GladeIDAllocator *id_allocator;
+	GList            *free_ids = NULL, *l;
 	const gchar      *number;
 	gchar            *name = NULL, *freeme = NULL;
-	guint             i = 1;
-	
+	guint             i;
+	gboolean          found = FALSE;
+
 	g_return_val_if_fail (context != NULL, NULL);
 	g_return_val_if_fail (another_context != NULL, NULL);
 	g_return_val_if_fail (base_name && base_name[0], NULL);
@@ -130,11 +132,11 @@ glade_name_context_dual_new_name (GladeNameContext *context,
 		--number;
 
 	if (*number)
-        {
+	{
 		freeme = g_strndup (base_name, number - base_name);
 		base_name = freeme;
 	}
-	
+
 	id_allocator = g_hash_table_lookup (context->name_allocators, base_name);
 
 	if (id_allocator == NULL)
@@ -143,15 +145,28 @@ glade_name_context_dual_new_name (GladeNameContext *context,
 		g_hash_table_insert (context->name_allocators,
 				     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);
-	} 
-	while (glade_name_context_has_name (context, name) ||
-	       glade_name_context_has_name (another_context, name));
+		
+		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));
+	}
+
+	/* 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;
@@ -221,17 +236,12 @@ glade_name_context_release_name (GladeNameContext *context,
 	}
 	while (TRUE);
 
-	/* if there is a number - then we have to unallocate it... */
-	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);
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 4b5e0f0..163290e 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -2837,7 +2837,6 @@ glade_project_release_widget_name (GladeProject *project, GladeWidget *gwidget,
 		g_free (tinfo);
 		project->priv->toplevels = g_list_remove (project->priv->toplevels, tinfo);
 	}
-
 }
 
 /**



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