evas: Ensure post-event cb push is called from an event cb
authorJean-Philippe Andre <jp.andre@samsung.com>
Thu, 16 Feb 2017 07:26:42 +0000 (16:26 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 16 Feb 2017 07:26:42 +0000 (16:26 +0900)
This rejects calls to evas_post_event_callback_push() that don't
originate from inside an input event callback.

src/lib/evas/canvas/evas_callbacks.c
src/lib/evas/canvas/evas_main.c
src/lib/evas/include/evas_private.h

index 2b4e88e..da5bb48 100644 (file)
@@ -252,6 +252,8 @@ _evas_post_event_callback_free(Evas *eo_e)
    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
    Evas_Post_Callback *pc;
 
+   if (EINA_LIKELY(!e->post_events)) return;
+
    EINA_LIST_FREE(e->post_events, pc)
      {
         EVAS_MEMPOOL_FREE(_mp_pc, pc);
@@ -323,6 +325,7 @@ evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data
    /* MEM OK */
    const Evas_Button_Flags CLICK_MASK = EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK;
    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+   Evas_Callback_Type prev_type;
    Evas_Public_Data *e;
 
    if (!obj) return;
@@ -364,27 +367,41 @@ evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data
         efl_event_desc = _legacy_evas_callback_table(type);
      }
 
+   prev_type = e->current_event;
+   e->current_event = type;
+
    efl_event_callback_legacy_call(eo_obj, efl_event_desc, event_info);
 
    /* multi events with finger 0 - only for eo callbacks */
    if (type == EVAS_CALLBACK_MOUSE_DOWN)
      {
         if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_DOWN))
-          efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_DOWN, event_info);
+          {
+             e->current_event = EVAS_CALLBACK_MULTI_DOWN;
+             efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_DOWN, event_info);
+          }
         efl_input_pointer_button_flags_set(event_info, flags);
      }
    else if (type == EVAS_CALLBACK_MOUSE_UP)
      {
         if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_UP))
-          efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_UP, event_info);
+          {
+             e->current_event = EVAS_CALLBACK_MULTI_UP;
+             efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_UP, event_info);
+          }
         efl_input_pointer_button_flags_set(event_info, flags);
      }
    else if (type == EVAS_CALLBACK_MOUSE_MOVE)
      {
         if (_evas_object_callback_has_by_type(obj, EVAS_CALLBACK_MULTI_MOVE))
-          efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_MOVE, event_info);
+          {
+             e->current_event = EVAS_CALLBACK_MULTI_MOVE;
+             efl_event_callback_call(eo_obj, EFL_EVENT_FINGER_MOVE, event_info);
+          }
      }
 
+   e->current_event = prev_type;
+
 nothing_here:
    if (!obj->no_propagate)
      {
@@ -580,6 +597,11 @@ evas_post_event_callback_push(Evas *eo_e, Evas_Object_Event_Post_Cb func, const
    Evas_Post_Callback *pc;
 
    if (!e || e->delete_me) return;
+   if (e->current_event == EVAS_CALLBACK_LAST)
+     {
+        ERR("%s() can only be called from an input event callback!", __FUNCTION__);
+        return;
+     }
    EVAS_MEMPOOL_INIT(_mp_pc, "evas_post_callback", Evas_Post_Callback, 64, );
    pc = EVAS_MEMPOOL_ALLOC(_mp_pc, Evas_Post_Callback);
    if (!pc) return;
index 3a1aa0e..fff28b4 100644 (file)
@@ -214,6 +214,7 @@ _evas_canvas_efl_object_constructor(Eo *eo_obj, Evas_Public_Data *e)
    e->framespace.w = 0;
    e->framespace.h = 0;
    e->hinting = EVAS_FONT_HINTING_BYTECODE;
+   e->current_event = EVAS_CALLBACK_LAST;
    e->name_hash = eina_hash_string_superfast_new(NULL);
    eina_clist_init(&e->calc_list);
    eina_clist_init(&e->calc_done);
index a62852a..ff28339 100644 (file)
@@ -929,6 +929,7 @@ struct _Evas_Public_Data
    int            last_mouse_up_counter;
    int            nochange;
    Evas_Font_Hinting_Flags hinting;
+   Evas_Callback_Type current_event;
 
    Eina_List     *touch_points;
    Eina_List     *devices;