efl_ui_table: hardening of pack_at function
authorMarcel Hollerbach <mail@marcel-hollerbach.de>
Thu, 4 Apr 2019 11:24:59 +0000 (13:24 +0200)
committerYeongjong Lee <yj34.lee@samsung.com>
Wed, 24 Apr 2019 05:24:47 +0000 (14:24 +0900)
_pack_at is used to add new subobjects to the table. When a object is
already part of this table, then we should not add it again. Additional,
when there is already a gi structure, but the parent is something else,
then we should NOT just reuse this struct, otherwise we might use a
struct reference that we do not own. The struct could be owned by
another table widget.

The test must be adjusted, before we did not error on adding a widget
twice. Now we do (just like in box). Hence we should not do that in
test.

Reviewed-by: YeongJong Lee <yj34.lee@samsung.com>
Differential Revision: https://phab.enlightenment.org/D8554

src/lib/elementary/efl_ui_table.c
src/tests/elementary/efl_ui_test_table.c

index 50fd0be834ee559406a169c5bac284651fba408c..136e2f2473152402ceb315f134675cea8a785f95 100644 (file)
@@ -306,6 +306,18 @@ _pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj,
 
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
 
+   gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
+
+   if (gi && efl_ui_widget_parent_get(subobj) == obj)
+     {
+        ERR("subobj %p %s is already added to this", subobj, efl_class_name_get(subobj) );
+        return EINA_FALSE;
+     }
+   else if (gi &&  efl_ui_widget_parent_get(subobj) != obj)
+     {
+        gi = NULL;
+     }
+
    if (col < 0) col = 0;
    if (row < 0) row = 0;
 
@@ -327,22 +339,10 @@ _pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj,
             col, row, colspan, rowspan, pd->req_cols, pd->req_rows);
      }
 
-   if (obj == elm_widget_parent_widget_get(subobj))
-     {
-        gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
-        if (gi)
-          {
-             gi->col = col;
-             gi->row = row;
-             gi->col_span = colspan;
-             gi->row_span = rowspan;
-             gi->linear = EINA_FALSE;
-          }
-        else ERR("object is a child but internal data was not found!");
-     }
-
    if (!gi)
      {
+        if (!elm_widget_sub_object_add(obj, subobj))
+          return EINA_FALSE;
         gi = calloc(1, sizeof(*gi));
         if (!gi) return EINA_FALSE;
         gi->col = col;
@@ -356,7 +356,6 @@ _pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj,
               eina_inlist_append(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
 
         efl_key_data_set(subobj, TABLE_ITEM_KEY, gi);
-        elm_widget_sub_object_add(obj, subobj);
         efl_event_callback_legacy_call(obj, EFL_CONTAINER_EVENT_CONTENT_ADDED, subobj);
         efl_event_callback_array_add(subobj, subobj_callbacks(), obj);
      }
index ac96db58e9f1042d19644ba69f62dc74decc83ee..f299fdd9bc6c54a32a374510e1e4fa7114b28b31 100644 (file)
@@ -341,11 +341,12 @@ EFL_START_TEST (efl_ui_table_layout_update_matrix)
      {
         for (j = 0; j < 3; j++)
         {
-           btn[3 * i + j] = efl_add(EFL_UI_BUTTON_CLASS, layout,
-                                    efl_pack_table(layout, efl_added, i, j, 1, 1));
+           btn[3 * i + j] = efl_add(EFL_UI_BUTTON_CLASS, layout);
 
            if ((i == 2) && (j == 1))
              efl_pack_table(layout, btn[3 * i + j], i, j, 1, 2);
+           else
+             efl_pack_table(layout, btn[3 * i + j], i, j, 1, 1);
         }
      }
    for (i = 0; i < max_index; i++)