cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=ac0b42a51a756ab15416aadeeb053eff7ed77d53

commit ac0b42a51a756ab15416aadeeb053eff7ed77d53
Author: Vitalii Vorobiov <vi.vorob...@samsung.com>
Date:   Thu Jan 29 21:21:05 2015 +0100

    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 <ced...@osg.samsung.com>
---
 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 19edf94..4f582c7 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 &&

-- 


Reply via email to