From cc3caf6172f63d081d8128924a76f6692929821f Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 9 May 2012 07:09:59 +0000 Subject: [PATCH] edje: prevent segv when edje_object_signal_emit get nested and edje_object_signal_callback_{add,del} are called. SVN revision: 70880 --- legacy/edje/ChangeLog | 4 ++++ legacy/edje/NEWS | 1 + legacy/edje/src/lib/edje_private.h | 5 +++-- legacy/edje/src/lib/edje_program.c | 9 +++++---- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/legacy/edje/ChangeLog b/legacy/edje/ChangeLog index ed36acc0c2..aa22a7d70b 100644 --- a/legacy/edje/ChangeLog +++ b/legacy/edje/ChangeLog @@ -427,3 +427,7 @@ 2012-05-08 Cedric Bail * Add edje_watch tools to automatically rebuild edc. + +2012-05-09 Cedric Bail + + * Fix bug in case of nesting edje_object_signal_emit and edje_object_signal_callback_{add,del} diff --git a/legacy/edje/NEWS b/legacy/edje/NEWS index 87c57ba2e4..c9bc3e97b7 100644 --- a/legacy/edje/NEWS +++ b/legacy/edje/NEWS @@ -11,6 +11,7 @@ Improvements: Fixes: * Add missing files in the tarballs. + * Prevent crash when running nested edje_object_signal_emit with edje_object_signal_callback_{add,del}. Edje 1.2.0 diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 1d5aee9ed8..85c312f431 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -1148,9 +1148,10 @@ struct _Edje void *data; } item_provider; + int walking_callbacks; + unsigned int dirty : 1; unsigned int recalc : 1; - unsigned int walking_callbacks : 1; unsigned int delete_callbacks : 1; unsigned int just_added_callbacks : 1; unsigned int have_objects : 1; @@ -1807,7 +1808,7 @@ void _edje_textblock_styles_del(Edje *ed); void _edje_textblock_style_all_update(Edje *ed); void _edje_textblock_style_parse_and_fix(Edje_File *edf); void _edje_textblock_style_cleanup(Edje_File *edf); -Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret); +Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed); void _edje_cache_coll_clean(Edje_File *edf); void _edje_cache_coll_flush(Edje_File *edf); void _edje_cache_coll_unref(Edje_File *edf, Edje_Part_Collection *edc); diff --git a/legacy/edje/src/lib/edje_program.c b/legacy/edje/src/lib/edje_program.c index 575a3285ef..407d2130d6 100644 --- a/legacy/edje/src/lib/edje_program.c +++ b/legacy/edje/src/lib/edje_program.c @@ -1289,7 +1289,7 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da if (ed->just_added_callbacks) _edje_callbacks_patterns_clean(ed); - ed->walking_callbacks = 1; + ed->walking_callbacks++; if (ed->callbacks) { @@ -1321,14 +1321,15 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da { escb->func(escb->data, ed->obj, sig, src); if (_edje_block_break(ed)) - goto break_prog; + break; } } } break_prog: - ed->walking_callbacks = 0; - if ((ed->delete_callbacks) || (ed->just_added_callbacks)) + ed->walking_callbacks--; + if (!ed->walking_callbacks && + ((ed->delete_callbacks) || (ed->just_added_callbacks))) { ed->delete_callbacks = 0; ed->just_added_callbacks = 0;