summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYeongJong Lee <yj34.lee@samsung.com>2018-01-11 09:23:29 +0100
committerMarcel Hollerbach <marcel@osg.samsung.com>2018-01-11 09:51:59 +0100
commit1b4f330c9c4dea9b08fb227cfca1f69fe59fccd3 (patch)
treea721dd59b94ce3877083f59e9805b64479194c8d
parentaf681a10915aadbc2af53522be03ba7c60af046a (diff)
efl_ui_focus_manager_calc: store node data before the node is freed
Summary: we can consider that the node is freed during focus_manager routine. for example, efl_ui_focus_manager_redirect_set call edje event callbacks, and a application can delete a object in the edje callback. if the object is the focusable object of a node, focus_manager make the node freed. the focus_manager is able to use freed node. (a good example is test_popup.c) this prevent reusing freed pointers. Test Plan: 1. elementary_test -to popup 2. popup-center-text + 1 button 3. Click the Close button 4. check that there is no erroe message Reviewers: bu5hm4n Reviewed By: bu5hm4n Subscribers: cedric, woohyun, jpeg, Jaehyun_Cho Differential Revision: https://phab.enlightenment.org/D5729
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_calc.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c
index 78475588f6..c8641b5338 100644
--- a/src/lib/elementary/efl_ui_focus_manager_calc.c
+++ b/src/lib/elementary/efl_ui_focus_manager_calc.c
@@ -1487,8 +1487,9 @@ EOLIAN static void
1487_efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *focus) 1487_efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *focus)
1488{ 1488{
1489 Node *node, *last; 1489 Node *node, *last;
1490 Efl_Ui_Focus_Object *last_focusable = NULL; 1490 Efl_Ui_Focus_Object *last_focusable = NULL, *new_focusable;
1491 Efl_Ui_Focus_Manager *redirect_manager; 1491 Efl_Ui_Focus_Manager *redirect_manager;
1492 Node_Type node_type;
1492 1493
1493 EINA_SAFETY_ON_NULL_RETURN(focus); 1494 EINA_SAFETY_ON_NULL_RETURN(focus);
1494 1495
@@ -1531,6 +1532,19 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
1531 return; 1532 return;
1532 } 1533 }
1533 1534
1535 node_type = node->type;
1536 new_focusable = node->focusable;
1537
1538 redirect_manager = node->redirect_manager;
1539
1540 last = eina_list_last_data_get(pd->focus_stack);
1541 if (last)
1542 last_focusable = last->focusable;
1543
1544 //remove the object from the list and add it again
1545 pd->focus_stack = eina_list_remove(pd->focus_stack, node);
1546 pd->focus_stack = eina_list_append(pd->focus_stack, node);
1547
1534 if (pd->redirect) 1548 if (pd->redirect)
1535 { 1549 {
1536 Efl_Ui_Focus_Manager *m = obj; 1550 Efl_Ui_Focus_Manager *m = obj;
@@ -1545,31 +1559,21 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
1545 } 1559 }
1546 } 1560 }
1547 1561
1548 redirect_manager = node->redirect_manager; 1562 //set to NULL here, from the event earlier this pointer could be dead.
1549 1563 node = NULL;
1550 last = eina_list_last_data_get(pd->focus_stack);
1551 if (last)
1552 last_focusable = last->focusable;
1553
1554 //remove the object from the list and add it again
1555 pd->focus_stack = eina_list_remove(pd->focus_stack, node);
1556 pd->focus_stack = eina_list_append(pd->focus_stack, node);
1557 1564
1558 /* 1565 /*
1559 Only emit those signals if we are already at the top of the focus stack. 1566 Only emit those signals if we are already at the top of the focus stack.
1560 Otherwise focus_get in the callback to that signal might return false. 1567 Otherwise focus_get in the callback to that signal might return false.
1561 */ 1568 */
1562 if (node->type == NODE_TYPE_NORMAL) 1569 if (node_type == NODE_TYPE_NORMAL)
1563 { 1570 {
1564 //populate the new change 1571 //populate the new change
1565 efl_ui_focus_object_focus_set(last_focusable, EINA_FALSE); 1572 efl_ui_focus_object_focus_set(last_focusable, EINA_FALSE);
1566 efl_ui_focus_object_focus_set(node->focusable, EINA_TRUE); 1573 efl_ui_focus_object_focus_set(new_focusable, EINA_TRUE);
1567 efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, last_focusable); 1574 efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, last_focusable);
1568 } 1575 }
1569 1576
1570 //set to NULL here, from the event earlier this pointer could be dead.
1571 node = NULL;
1572
1573 //now check if this is also a listener object 1577 //now check if this is also a listener object
1574 if (redirect_manager) 1578 if (redirect_manager)
1575 { 1579 {