From f83575371ea8555c82101e7af761df92fef5a20d Mon Sep 17 00:00:00 2001 From: Christian Stimming Date: Sat, 6 Dec 2008 21:33:14 +0000 Subject: [PATCH] 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 --- src/register/register-gnome/gnucash-sheet.c | 8 +++++--- src/register/register-gnome/gnucash-style.c | 11 ++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/register/register-gnome/gnucash-sheet.c b/src/register/register-gnome/gnucash-sheet.c index 2c8f184e40..28078a823f 100644 --- a/src/register/register-gnome/gnucash-sheet.c +++ b/src/register/register-gnome/gnucash-sheet.c @@ -2367,7 +2367,8 @@ gnucash_sheet_init (GnucashSheet *sheet) sheet->width = 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), gnucash_sheet_block_construct, @@ -2426,8 +2427,9 @@ gnucash_sheet_new (Table *table) sheet->grid = item; /* some register data */ - sheet->dimensions_hash_table = g_hash_table_new (g_int_hash, - g_int_equal); + sheet->dimensions_hash_table = g_hash_table_new_full (g_int_hash, + g_int_equal, + g_free, NULL); /* The cursor */ sheet->cursor = gnucash_cursor_new (sheet_group); diff --git a/src/register/register-gnome/gnucash-style.c b/src/register/register-gnome/gnucash-style.c index f3df080b8a..8b767a5b4c 100644 --- a/src/register/register-gnome/gnucash-style.c +++ b/src/register/register-gnome/gnucash-style.c @@ -48,6 +48,15 @@ style_get_key (SheetBlockStyle *style) 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 cell_dimensions_construct (gpointer _cd, gpointer user_data) @@ -103,7 +112,7 @@ gnucash_style_dimensions_init (GnucashSheet *sheet, SheetBlockStyle *style) if (!dimensions) { dimensions = style_dimensions_new (style); g_hash_table_insert (sheet->dimensions_hash_table, - style_get_key (style), dimensions); + style_create_key (style), dimensions); } dimensions->refcount++;