diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ChangeLog.ja | 7 | ||||
-rw-r--r-- | src/addrcache.c | 60 | ||||
-rw-r--r-- | src/addressbook.c | 4 |
4 files changed, 52 insertions, 25 deletions
@@ -1,5 +1,11 @@ 2007-04-17 + * src/addrcache.c + src/addressbook.c: fixed a crash bug that if a person was removed + and its e-mail address was referenced by a group in another folder. + +2007-04-17 + * libsylph/session.[ch]: remove idle callback on close, and check GSource in the callback (possibly fixes crashes on cancellation). diff --git a/ChangeLog.ja b/ChangeLog.ja index 08410396..d2853c88 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,5 +1,12 @@ 2007-04-17 + * src/addrcache.c + src/addressbook.c: 人物を削除したとき、そのメールアドレスが他 + フォルダのグループによって参照されている場合クラッシュするバグを + 修正。 + +2007-04-17 + * libsylph/session.[ch]: クローズ時に idle コールバックを削除する ようにし、コールバック中で GSource をチェックするようにした (キャンセル時のクラッシュを恐らく修正)。 diff --git a/src/addrcache.c b/src/addrcache.c index 9f538e0c..a28a62ba 100644 --- a/src/addrcache.c +++ b/src/addrcache.c @@ -681,22 +681,43 @@ ItemGroup *addrcache_remove_group( AddressCache *cache, ItemGroup *group ) { } /* -* Remove person's email address from all groups in folder. +* Remove person's email addresses from all groups. */ -static void addrcache_foldergrp_rem_person( ItemFolder *folder, ItemPerson *person ) { - GList *nodeGrp = folder->listGroup; +static void addrcache_allgrp_rem_person_vis( gpointer key, gpointer value, gpointer data ) { + AddrItemObject *obj = ( AddrItemObject * ) value; + ItemPerson *person = ( ItemPerson * ) data; + + if ( !person ) return; - while( nodeGrp ) { - ItemGroup *group = nodeGrp->data; + if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { + ItemGroup *group = ( ItemGroup * ) obj; if( group ) { /* Remove each email address that belongs to the person from the list */ GList *node = person->listEMail; + debug_print("removing email in person %p (%s) from group %p (%s)\n", person, ADDRITEM_NAME(person), group, ADDRITEM_NAME(group)); while( node ) { group->listEMail = g_list_remove( group->listEMail, node->data ); node = g_list_next( node ); } } - nodeGrp = g_list_next( nodeGrp ); + } +} + +/* +* Remove email from group item hash table visitor function. +*/ +static void addrcache_allgrp_rem_email_vis( gpointer key, gpointer value, gpointer data ) { + AddrItemObject *obj = ( AddrItemObject * ) value; + ItemEMail *email = ( ItemEMail * ) data; + + if( !email ) return; + if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { + ItemGroup *group = ( ItemGroup * ) value; + if( group ) { + debug_print("removing email %p (%s) from group %p (%s)\n", email, email->address, group, ADDRITEM_NAME(group)); + /* Remove each email address that belongs to the person from the list */ + group->listEMail = g_list_remove( group->listEMail, email ); + } } } @@ -716,6 +737,9 @@ ItemPerson *addrcache_remove_person_id( AddressCache *cache, const gchar *uid ) obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); if( obj ) { if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { + ItemEMail *email; + GList *list; + /* Remove person's email addresses from all groups where */ /* referenced and from hash table. */ ItemPerson *person = ( ItemPerson * ) obj; @@ -723,7 +747,7 @@ ItemPerson *addrcache_remove_person_id( AddressCache *cache, const gchar *uid ) if( ! parent ) parent = cache->rootFolder; /* Remove emails from groups, remove from parent's list */ /* and hash table */ - addrcache_foldergrp_rem_person( parent, person ); + g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_person_vis, person ); parent->listPerson = g_list_remove( parent->listPerson, person ); g_hash_table_remove( cache->itemHash, uid ); return person; @@ -748,11 +772,14 @@ ItemPerson *addrcache_remove_person( AddressCache *cache, ItemPerson *person ) { obj = ( AddrItemObject * ) g_hash_table_lookup( cache->itemHash, uid ); if( obj ) { if( ADDRITEM_TYPE(obj) == ITEMTYPE_PERSON ) { + ItemEMail *email; + GList *list; + /* Remove person's email addresses from all groups where */ /* referenced and from hash table. */ ItemFolder *parent = ( ItemFolder * ) ADDRITEM_PARENT(person); if( ! parent ) parent = cache->rootFolder; - addrcache_foldergrp_rem_person( parent, person ); + g_hash_table_foreach( cache->itemHash, addrcache_allgrp_rem_person_vis, person ); parent->listPerson = g_list_remove( parent->listPerson, person ); g_hash_table_remove( cache->itemHash, uid ); return person; @@ -763,23 +790,6 @@ ItemPerson *addrcache_remove_person( AddressCache *cache, ItemPerson *person ) { } /* -* Remove email from group item hash table visitor function. -*/ -static void addrcache_allgrp_rem_email_vis( gpointer key, gpointer value, gpointer data ) { - AddrItemObject *obj = ( AddrItemObject * ) value; - ItemEMail *email = ( ItemEMail * ) data; - - if( !email ) return; - if( ADDRITEM_TYPE(obj) == ITEMTYPE_GROUP ) { - ItemGroup *group = ( ItemGroup * ) value; - if( group ) { - /* Remove each email address that belongs to the person from the list */ - group->listEMail = g_list_remove( group->listEMail, email ); - } - } -} - -/* * Remove email address in address cache for specified ID. * param: uid Object ID for person. * eid EMail ID. diff --git a/src/addressbook.c b/src/addressbook.c index a515dcb3..09a89316 100644 --- a/src/addressbook.c +++ b/src/addressbook.c @@ -2053,6 +2053,10 @@ static void addressbook_load_group( GtkCTree *clist, ItemGroup *itemGroup ) { if( ! email ) continue; person = ( ItemPerson * ) ADDRITEM_PARENT(email); + if( ! person ) { + g_warning("email %p (%s) don't have parent\n", email, email->address); + continue; + } str = addressbook_format_item_clist( person, email ); if( str ) { text[COL_NAME] = str; |