zmike pushed a commit to branch master.

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

commit 333a0709152241f08771a95cc5315afef74b5f3e
Author: Marcel Hollerbach <m...@marcel-hollerbach.de>
Date:   Fri Aug 30 14:50:32 2019 -0400

    efl_ui_collection: prevent the invalid insertion of items.
    
    Summary:
    the group hirachy that you can build up with group items is flattend
    down in the collection, as a linear list. Based on that a user might be
    able to insert items at invalid positions, like between groups, without
    having set the proper group item, which ... is a problem.
    
    This commit ensures that no new item ever destroys the neightboor hood
    between two items of the same group or a item with a group and its group
    leader.
    
    Reviewers: stefan_schmidt, zmike, segfaultxavi, SanghyeonLee
    
    Reviewed By: SanghyeonLee
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D9778
---
 src/lib/elementary/efl_ui_collection.c             | 50 ++++++++++++++++++++++
 .../elementary/efl_ui_test_collection_common.c     | 38 +++++++++++++++-
 2 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/src/lib/elementary/efl_ui_collection.c 
b/src/lib/elementary/efl_ui_collection.c
index eef694e3e0..a3ad0daf57 100644
--- a/src/lib/elementary/efl_ui_collection.c
+++ b/src/lib/elementary/efl_ui_collection.c
@@ -700,6 +700,53 @@ update_pos_man(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data 
*pd, Efl_Gfx_Entity *
    efl_ui_position_manager_entity_item_added(pd->pos_man, id, subobj);
 }
 
+static inline Efl_Ui_Item*
+fetch_rep_parent(Eina_List *lst)
+{
+   if (!lst)
+     return NULL;
+
+   Efl_Ui_Item *it = eina_list_data_get(lst);
+
+   return efl_ui_item_parent_get(it);
+}
+
+static Eina_Bool
+check_group_integrity(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, 
Efl_Gfx_Entity *subobj)
+{
+   Eina_List *carrier_list = eina_list_data_find_list(pd->items, subobj), 
*prev_lst;
+   Efl_Ui_Item *next, *prev, *carrier;
+
+   prev_lst = eina_list_prev(carrier_list);
+   next = fetch_rep_parent(eina_list_next(carrier_list));
+   prev = fetch_rep_parent(prev_lst);
+   carrier = fetch_rep_parent(carrier_list);
+
+   if (next && next == prev && carrier != prev)
+     {
+        //a item got inserted into the middle of one group, but does not have 
the correct group header, that is a bug
+        ERR("Inserting a item with the wrong group into another 
group(%p,%p,%p)", prev, carrier, next);
+        unregister_item(obj, pd, subobj);
+        return EINA_FALSE;
+     }
+
+   if (prev_lst && eina_list_data_get(prev_lst) == next && carrier != next)
+     {
+        //a item got inserted between group header and group children, also a 
error
+        ERR("Inserting a item between group header, and group 
elements(%p,%p,%p)", prev_lst, eina_list_data_get(prev_lst), next);
+        unregister_item(obj, pd, subobj);
+        return EINA_FALSE;
+     }
+   if (!next && !prev && carrier && prev_lst && eina_list_data_get(prev_lst) 
!= carrier)
+     {
+        ERR("Tried to insert a item with group, outside its group(%p,%p,%p)", 
next, prev, carrier);
+        unregister_item(obj, pd, subobj);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
 EOLIAN static Eina_Bool
 _efl_ui_collection_efl_pack_pack_clear(Eo *obj EINA_UNUSED, 
Efl_Ui_Collection_Data *pd)
 {
@@ -779,6 +826,7 @@ _efl_ui_collection_efl_pack_linear_pack_before(Eo *obj, 
Efl_Ui_Collection_Data *
    if (!register_item(obj, pd, subobj))
      return EINA_FALSE;
    pd->items = eina_list_prepend_relative_list(pd->items, subobj, subobj_list);
+   if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE;
    update_pos_man(obj, pd, subobj);
    return EINA_TRUE;
 }
@@ -792,6 +840,7 @@ _efl_ui_collection_efl_pack_linear_pack_after(Eo *obj, 
Efl_Ui_Collection_Data *p
    if (!register_item(obj, pd, subobj))
      return EINA_FALSE;
    pd->items = eina_list_append_relative_list(pd->items, subobj, subobj_list);
+   if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE;
    update_pos_man(obj, pd, subobj);
    return EINA_TRUE;
 }
@@ -814,6 +863,7 @@ _efl_ui_collection_efl_pack_linear_pack_at(Eo *obj, 
Efl_Ui_Collection_Data *pd,
      pd->items = eina_list_append(pd->items, subobj);
    else
      pd->items = eina_list_prepend(pd->items, subobj);
+   if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE;
    update_pos_man(obj, pd, subobj);
    return EINA_TRUE;
 }
diff --git a/src/tests/elementary/efl_ui_test_collection_common.c 
b/src/tests/elementary/efl_ui_test_collection_common.c
index 7be3c7c532..5bd2c5cd55 100644
--- a/src/tests/elementary/efl_ui_test_collection_common.c
+++ b/src/tests/elementary/efl_ui_test_collection_common.c
@@ -22,6 +22,42 @@ fill_items(const Efl_Class *klass)
     }
 }
 
-void efl_ui_test_item_container_common_add(TCase *tc EINA_UNUSED)
+EFL_START_TEST(finalizer_group_middle_insert)
 {
+   Efl_Ui_Group_Item *group_item = efl_add(EFL_UI_GROUP_ITEM_CLASS, 
item_container);
+   efl_pack_end(item_container, group_item);
+   Efl_Ui_Group_Item *i1 = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, 
item_container);
+   efl_pack_end(group_item, i1);
+   Efl_Ui_Group_Item *i2 = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, 
item_container);
+   efl_pack_end(group_item, i2);
+   Efl_Ui_Group_Item *e = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, 
item_container);
+
+   EXPECT_ERROR_START;
+   efl_pack_after(item_container, e, group_item);
+   EXPECT_ERROR_END;
+   EXPECT_ERROR_START;
+   efl_pack_after(item_container, e, i1);
+   EXPECT_ERROR_END;
+
+   EXPECT_ERROR_START;
+   efl_pack_before(item_container, e, i1);
+   EXPECT_ERROR_END;
+   EXPECT_ERROR_START;
+   efl_pack_before(item_container, e, i2);
+   EXPECT_ERROR_END;
+
+   EXPECT_ERROR_START;
+   efl_pack_at(item_container, e, 1);
+   EXPECT_ERROR_END;
+   EXPECT_ERROR_START;
+   efl_pack_at(item_container, e, 2);
+   EXPECT_ERROR_END;
+
+   efl_del(item_container);
+}
+EFL_END_TEST
+
+void efl_ui_test_item_container_common_add(TCase *tc)
+{
+   tcase_add_test(tc, finalizer_group_middle_insert);
 }

-- 


Reply via email to