From ac0b42a51a756ab15416aadeeb053eff7ed77d53 Mon Sep 17 00:00:00 2001 From: Vitalii Vorobiov Date: Thu, 29 Jan 2015 21:21:05 +0100 Subject: [PATCH] Edje: edje_cc - abort recursive Reference that is made by GROUP parts Summary: It is easy to create edj collections that aren't working at all and edje_cc easily allows user to do that. For example: > Having group A with GROUP part that has group B as source. > Having group B with GROUP part that has group A as source. In this case edje_cc compile source code perfectly, but if user try to load this edje as layout or use together with edje_edit it will cause unexpacted and wrong behaviour. @fix Reviewers: seoz, Hermet, reutskiy.v.v, cedric Reviewed By: cedric Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D1908 Signed-off-by: Cedric BAIL --- src/bin/edje/edje_cc_out.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c index 19edf9420c..4f582c779c 100755 --- a/src/bin/edje/edje_cc_out.c +++ b/src/bin/edje/edje_cc_out.c @@ -369,6 +369,51 @@ check_image_part_desc(Edje_Part_Collection *pc, Edje_Part *ep, } } +/* This function check loops between groups. + For example: + > part in group A. It's source is B. + > part in group B. It's source is C. + > part in group C. It's source is A <- here is error. + It's loop that we need to avoid! */ +static void +check_source_links(Edje_Part_Collection *pc, Edje_Part *ep, Eet_File *ef, Eina_List *group_path) +{ + unsigned int i; + char *data; + Edje_Part_Collection *pc_source; + Eina_List *l; + + EINA_LIST_FOREACH(edje_collections, l, pc_source) + { + /* Find sourced group */ + if (strcmp(ep->source, pc_source->part) == 0) + { + /* Go through every part to find parts with type GROUP */ + for (i = 0; i < pc_source->parts_count; ++i) + { + if ((pc_source->parts[i]->type == EDJE_PART_TYPE_GROUP) && + (pc_source->parts[i]->source)) + { + /* Make sure that this group isn't already in the tree of parents */ + EINA_LIST_FOREACH(group_path, l, data) + { + if (data == pc_source->parts[i]->source) + { + error_and_abort(ef,"Recursive loop group '%s' " + "already included inside " + "part '%s' of group '%s'", + data, pc_source->parts[i]->name, + pc->part); + } + } + group_path = eina_list_append(group_path, ep->source); + check_source_links(pc, pc_source->parts[i], ef, group_path); + } + } + } + } +} + static void check_packed_items(Edje_Part_Collection *pc, Edje_Part *ep, Eet_File *ef) { @@ -410,6 +455,7 @@ static void check_part(Edje_Part_Collection *pc, Edje_Part *ep, Eet_File *ef) { unsigned int i; + Eina_List *group_path = NULL; /* FIXME: check image set and sort them. */ if (!ep->default_desc) error_and_abort(ef, "Collection %i: default description missing " @@ -428,6 +474,8 @@ check_part(Edje_Part_Collection *pc, Edje_Part *ep, Eet_File *ef) else if ((ep->type == EDJE_PART_TYPE_BOX) || (ep->type == EDJE_PART_TYPE_TABLE)) check_packed_items(pc, ep, ef); + else if (ep->type == EDJE_PART_TYPE_GROUP) + check_source_links(pc, ep, ef, group_path); /* FIXME: When mask are supported remove this check */ if (ep->clip_to_id != -1 &&