edje: Fix edje box crash

When a signal change a state of a edje box to a state that was already active
and we add/del a item of edje box a crash happen.

Example:
test.edc:

collections {
	group {
		name: "box_text";
		parts {
			part {
				name: "elm.box.buttons";
				type: BOX;
				description {
					state: "default" 0.0;
					min: 0 100;
					max: 9999 100;
					align: 0 0;
					box {
						layout: "horizontal";
						min: 1 1;
					}
					visible: 0;
				}
				description {
					state: "show" 0.0;
					inherit: "default" 0.0;
					visible: 1;
				}
			}
		}
		programs {
			program {
				signal: "show,buttons";
				source: "gui";
				action: STATE_SET "show" 0.0;
				transition: ACCELERATE 1;
				target: "elm.box.buttons";
			}
			program {
				signal: "hide,buttons";
				source: "gui";
				action: STATE_SET "default" 0.0;
				transition: ACCELERATE 1;
				target: "elm.box.buttons";
			}
		}
	}
}

test.c:

//Compile with:
//gcc -g test.c -o test `pkg-config --cflags --libs elementary edje ecore`

static int count = 0;

static Eina_Bool _fill(void *data)
{
	int i;
	Evas_Object *layout = data;
	Evas_Object *edje = elm_layout_edje_get(layout);

	edje_object_part_box_remove_all(edje, "elm.box.buttons", EINA_TRUE);
	elm_layout_signal_emit(layout, "show,buttons", "gui");

	printf("_fill()\n");

	for (i = 0; i < 5; i++, count++)
	{
		Evas_Object *btn;
		char buf[50];

		btn = elm_button_add(layout);
		snprintf(buf, sizeof(buf), "button %d", count);
		elm_object_text_set(btn, buf);
		edje_object_part_box_append(edje, "elm.box.buttons", btn);
		evas_object_show(btn);
	}

	return EINA_TRUE;
}

EAPI_MAIN int
elm_main(int argc, char **argv)
{
	Evas_Object *win, *bg, *layout;

	win = elm_win_add(NULL, "test", ELM_WIN_BASIC);
	elm_win_title_set(win, "Test");
	elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
   	elm_win_autodel_set(win, EINA_TRUE);

	bg = elm_bg_add(win);
	elm_bg_color_set(bg, 255, 255, 255);
	evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	elm_win_resize_object_add(win, bg);
	evas_object_show(bg);

	layout = elm_layout_add(win);
	elm_layout_file_set(layout, "test.edj", "box_text");
	evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	evas_object_show(layout);

	_fill(layout);
	ecore_timer_add(5, _fill, layout);

	evas_object_resize(win, 800, 320);
	evas_object_show(win);

	elm_run();
   	elm_shutdown();

   	return 0;
}
ELM_MAIN()

(gdb) bt
0x00000000 in ?? ()
0xb7add287 in _edje_box_layout_calculate_coords ()
   from /usr/lib/libedje.so.1
0xb7add5cd in _edje_box_layout () from /usr/lib/libedje.so.1
0xb7c98ff7 in _evas_object_box_smart_calculate ()
   from /usr/lib/libevas.so.1
0xb7c97a36 in evas_object_smart_calculate () from /usr/lib/libevas.so.1
0xb7ae1b12 in _edje_part_recalc_single () from /usr/lib/libedje.so.1
0xb7ae3380 in _edje_part_recalc () from /usr/lib/libedje.so.1
0xb7ae59ff in _edje_recalc_do () from /usr/lib/libedje.so.1
0xb7b3603a in _edje_smart_calculate () from /usr/lib/libedje.so.1
0xb7c97be2 in evas_call_smarts_calculate () from /usr/lib/libevas.so.1
0xb7cc7d88 in evas_render_updates_internal () from /usr/lib/libevas.so.1
0xb7ba7c97 in _ecore_evas_x_render () from /usr/lib/libecore_evas.so.1
0xb7ba27c6 in _ecore_evas_idle_enter () from /usr/lib/libecore_evas.so.1
0xb7c27212 in _ecore_idle_enterer_call () from /usr/lib/libecore.so.1
0xb7c28d3d in _ecore_main_loop_iterate_internal ()
   from /usr/lib/libecore.so.1
0xb7c2941f in ecore_main_loop_begin () from /usr/lib/libecore.so.1
0xb7e8def8 in elm_run () from /usr/lib/libelementary.so.1
0xb7f6f8ee in appcore_efl_main () from /usr/lib/libappcore-efl.so.1
0xb7644bb5 in app_efl_main () from /usr/lib/libcapi-appfw-application.so.0
0x08074c5a in main (argc=1, argv=0xbffffb64) at src/main_tizen.c:155

==2036== Jump to the invalid address stated on the next line
==2036==    at 0x0: ???
==2036==    by 0x44C35CC: _edje_box_layout (in /usr/lib/libedje.so.1.7.99)
==2036==    by 0x42E8FF6: _evas_object_box_smart_calculate (in /usr/lib/libevas.so.1.7.99)
==2036==    by 0x42E7A35: evas_object_smart_calculate (in /usr/lib/libevas.so.1.7.99)
==2036==    by 0x44C7B11: _edje_part_recalc_single (in /usr/lib/libedje.so.1.7.99)
==2036==    by 0x44C937F: _edje_part_recalc (in /usr/lib/libedje.so.1.7.99)
==2036==    by 0x44CB9FE: _edje_recalc_do (in /usr/lib/libedje.so.1.7.99)
==2036==    by 0x451C039: _edje_smart_calculate (in /usr/lib/libedje.so.1.7.99)
==2036==    by 0x42E7BE1: evas_call_smarts_calculate (in /usr/lib/libevas.so.1.7.99)
==2036==    by 0x4317D87: evas_render_updates_internal (in /usr/lib/libevas.so.1.7.99)
==2036==    by 0x4465C96: _ecore_evas_x_render (in /usr/lib/libecore_evas.so.1.7.99)
==2036==    by 0x44607C5: _ecore_evas_idle_enter (in /usr/lib/libecore_evas.so.1.7.99)
==2036==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

We called anim->start aftwards just to be sure to stick to something if
all fail.
This commit is contained in:
José Roberto de Souza 2013-05-17 18:44:24 -03:00 committed by Gustavo Lima Chaves
parent d1e38b8535
commit d5ebe804dd
1 changed files with 5 additions and 1 deletions

View File

@ -64,7 +64,11 @@ _edje_box_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv,
}
evas_object_box_padding_set(obj, anim->end.padding.x, anim->end.padding.y);
evas_object_box_align_set(obj, TO_DOUBLE(anim->end.align.x), TO_DOUBLE(anim->end.align.y));
anim->end.layout(obj, priv, anim->end.data);
if (anim->end.layout)
anim->end.layout(obj, priv, anim->end.data);
else if (anim->start.layout)
anim->start.layout(obj, priv, anim->start.data);
EINA_LIST_FOREACH(anim->objs, l, tad)
{
evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y,