better protect comp object internals from dereferencing freed clients

animating comp objects persist after the lifetime of their client, so
ensure that functions which are likely to be called after the client's free
will not attempt to access client struct members
This commit is contained in:
Mike Blumenkrantz 2017-03-03 11:56:16 -05:00
parent 54dfcea3e0
commit e618e00297
1 changed files with 13 additions and 6 deletions

View File

@ -104,7 +104,7 @@ typedef struct _E_Comp_Object
unsigned int animating; // it's busy animating
unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
unsigned int force_visible; //number of visible obj_mirror objects
Eina_Bool delete_pending : 1; // delete pending
Eina_Bool deleted : 1; // deleted
Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
Eina_Bool showing : 1; // object is currently in "show" animation
Eina_Bool visible : 1; // is visible
@ -235,7 +235,7 @@ _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj
{
E_Comp_Object *cw = data;
if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
if ((!cw->force_visible) && (!cw->deleted) && (!e_object_is_del(E_OBJECT(cw->ec))))
evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
cw->force_visible++;
}
@ -246,7 +246,7 @@ _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj
E_Comp_Object *cw = data;
cw->force_visible--;
if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
if ((!cw->force_visible) && (!cw->deleted) && (!e_object_is_del(E_OBJECT(cw->ec))))
evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
}
@ -2253,7 +2253,7 @@ _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void
{
E_Comp_Object *cw = data;
if (!e_object_is_del(E_OBJECT(cw->ec)))
if ((!cw->deleted) && (!e_object_is_del(E_OBJECT(cw->ec))))
e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
}
@ -2334,6 +2334,9 @@ _e_comp_smart_hide(Evas_Object *obj)
{
INTERNAL_ENTRY;
cw->visible = 0;
cw->deleted = e_object_is_del(E_OBJECT(cw->ec));
if (cw->deleted)
_e_comp_object_layers_remove(cw);
evas_object_hide(cw->clip);
if (cw->input_obj) evas_object_hide(cw->input_obj);
evas_object_hide(cw->effect_obj);
@ -2415,7 +2418,8 @@ _e_comp_smart_del(Evas_Object *obj)
INTERNAL_ENTRY;
e_comp_object_render_update_del(cw->smart_obj);
if (!cw->deleted)
e_comp_object_render_update_del(cw->smart_obj);
E_FREE_FUNC(cw->updates, eina_tiler_free);
E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
free(cw->ns);
@ -2425,6 +2429,8 @@ _e_comp_smart_del(Evas_Object *obj)
evas_object_image_data_set(o, NULL);
evas_object_freeze_events_set(o, 1);
evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
evas_object_event_callback_del_full(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
evas_object_event_callback_del_full(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
evas_object_del(o);
}
EINA_LIST_FREE(cw->obj_agent, o)
@ -2433,7 +2439,8 @@ _e_comp_smart_del(Evas_Object *obj)
evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_agent_del, cw);
evas_object_del(o);
}
_e_comp_object_layers_remove(cw);
if (!cw->deleted)
_e_comp_object_layers_remove(cw);
l = evas_object_data_get(obj, "comp_object-to_del");
E_FREE_LIST(l, evas_object_del);
evas_object_del(cw->clip);