furrymyad pushed a commit to branch master.

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

commit bac07e79cea59b1859e23d83028763e3f38c087a
Author: Vitalii Vorobiov <vi.vorob...@samsung.com>
Date:   Mon Feb 2 11:14:45 2015 +0200

    Edje: edje_edit - abort Recursive Reference in edje_edit_part_source_set
    
    It is unable to do recursive reference such as:
    >   Having group A with GROUP part that has group B as source.
    >   Having group B with GROUP part that has group A as source.
    Here we have a loop that is not allowed by edje_cc, so edje_edit also need
    to check this case.
    
    @fix
---
 src/lib/edje/Edje_Edit.h |  4 ++++
 src/lib/edje/edje_edit.c | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/src/lib/edje/Edje_Edit.h b/src/lib/edje/Edje_Edit.h
index 053a511..12db53b 100644
--- a/src/lib/edje/Edje_Edit.h
+++ b/src/lib/edje/Edje_Edit.h
@@ -1234,6 +1234,10 @@ EAPI const char * edje_edit_part_source_get(Evas_Object 
*obj, const char *part);
 
 /** Set the source of part.
  *
+ * If setting source of the part will lead to recursive reference
+ * (when A source to B, and B is going to be source to A because of this 
funciton),
+ * then it will return EINA_FALSE.
+ *
  * @param obj Object being edited.
  * @param part Part to set the source of.
  * @param source Value for the source parameter.
diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c
index 55a262d..d19a19a 100644
--- a/src/lib/edje/edje_edit.c
+++ b/src/lib/edje/edje_edit.c
@@ -3893,17 +3893,58 @@ edje_edit_part_source_get(Evas_Object *obj, const char 
*part)
    return eina_stringshare_add(rp->part->source);
 }
 
+static Eina_Bool
+_check_recursive_reference(Edje *ed, const char *source, Eina_List 
*group_path, Edje_Part *part)
+{
+   unsigned int i;
+   char *data;
+   Edje_Part_Collection_Directory_Entry *e;
+   Eina_List *l;
+   Eina_Bool no_ref = EINA_TRUE;
+
+   if (!source) return EINA_TRUE;
+
+   e = eina_hash_find(ed->file->collection, source);
+
+   /* Go through every part to find parts with type GROUP */
+   for (i = 0; i < e->ref->parts_count; ++i)
+     {
+        if ((e->ref->parts[i]->type == EDJE_PART_TYPE_GROUP) &&
+            (e->ref->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 == e->ref->parts[i]->source)
+                    return EINA_FALSE;
+               }
+             group_path = eina_list_append(group_path, source);
+             no_ref &= _check_recursive_reference(ed, 
e->ref->parts[i]->source, group_path, part);
+          }
+
+        /* We did a loop here... this part doesn't have source yet,
+           but if it will set, it'll be a recursive reference. */
+        if (e->ref->parts[i] == part) return EINA_FALSE;
+     }
+   return no_ref;
+}
+
 EAPI Eina_Bool
 edje_edit_part_source_set(Evas_Object *obj, const char *part, const char 
*source)
 {
    GET_RP_OR_RETURN(EINA_FALSE);
 
    Evas_Object *child_obj;
+   Eina_List *group_path = NULL;
    //printf("Set source for part: %s [source: %s]\n", part, source);
 
    switch (rp->part->type)
      {
       case EDJE_PART_TYPE_GROUP:
+        /* find source group */
+        if (!_check_recursive_reference(ed, source, group_path, rp->part))
+           return EINA_FALSE;
+
         if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
           {
              _edje_real_part_swallow_clear(ed, rp);

-- 


Reply via email to