Bug #563273: Fix crash on startup

Here's the problem... GnuCash uses a hash table with int keys to store
dimensions, and the key value is the number of rows in the dimension being
stored.  The problem is that this key value is stored in a static int inside
the style_get_key function, which means that the key always has the same
address, and the hash functions in glib2 store the *address*, not the *value*
of the key.  Unfortunately, the hash algorithm changed some time between
glib2-2.18.2 and glib2-2.19.2, such that there's a hash conflict between the
key value 1 and the key value 2, but since the value of the already hashed key
was swiped out from under it when style_get_key "created" a new key, the hash
table entry that's already there matches even when it shouldn't have.

The attached patch cleans this up by allocating memory to hold the key when
inserting it into the hash table.  It also changes the way the hash table is
created to ensure that the memory is freed when a hash table entry or hash
table is destroyed.  And while I was at it, I made the same fix for the cursors
hash table, which was also leaking memory when entries were removed or the
table was destroyed.

Patch by Jonathan Kamens.
BP

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@17747 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming 2008-12-06 21:33:14 +00:00
parent 957fab389d
commit f83575371e
2 changed files with 15 additions and 4 deletions

View File

@ -2367,7 +2367,8 @@ gnucash_sheet_init (GnucashSheet *sheet)
sheet->width = 0; sheet->width = 0;
sheet->height = 0; sheet->height = 0;
sheet->cursor_styles = g_hash_table_new (g_str_hash, g_str_equal); sheet->cursor_styles = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
sheet->blocks = g_table_new (sizeof (SheetBlock), sheet->blocks = g_table_new (sizeof (SheetBlock),
gnucash_sheet_block_construct, gnucash_sheet_block_construct,
@ -2426,8 +2427,9 @@ gnucash_sheet_new (Table *table)
sheet->grid = item; sheet->grid = item;
/* some register data */ /* some register data */
sheet->dimensions_hash_table = g_hash_table_new (g_int_hash, sheet->dimensions_hash_table = g_hash_table_new_full (g_int_hash,
g_int_equal); g_int_equal,
g_free, NULL);
/* The cursor */ /* The cursor */
sheet->cursor = gnucash_cursor_new (sheet_group); sheet->cursor = gnucash_cursor_new (sheet_group);

View File

@ -48,6 +48,15 @@ style_get_key (SheetBlockStyle *style)
return &key; return &key;
} }
static gpointer
style_create_key (SheetBlockStyle *style)
{
static gint key;
key = style->cursor->num_rows;
return g_memdup(&key, sizeof(key));
}
static void static void
cell_dimensions_construct (gpointer _cd, gpointer user_data) cell_dimensions_construct (gpointer _cd, gpointer user_data)
@ -103,7 +112,7 @@ gnucash_style_dimensions_init (GnucashSheet *sheet, SheetBlockStyle *style)
if (!dimensions) { if (!dimensions) {
dimensions = style_dimensions_new (style); dimensions = style_dimensions_new (style);
g_hash_table_insert (sheet->dimensions_hash_table, g_hash_table_insert (sheet->dimensions_hash_table,
style_get_key (style), dimensions); style_create_key (style), dimensions);
} }
dimensions->refcount++; dimensions->refcount++;