mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
957fab389d
commit
f83575371e
@ -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);
|
||||||
|
@ -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++;
|
||||||
|
Loading…
Reference in New Issue
Block a user