From f387818a55e9871f3e93ab0f83515919c527d69b Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Thu, 29 Sep 2016 14:14:43 +0900 Subject: [PATCH] eo - fix error case lock not unlocking with shared objects from coverity this fixes CID 1363294 --- src/lib/eo/eo.c | 23 ++++++--- src/lib/eo/eo_ptr_indirection.h | 91 +++++++++++++++++++++++++-------- 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index c3ae836e31..a80027ae46 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1469,8 +1469,8 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id) return isa; } - EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE); - EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE); + EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj); + EO_CLASS_POINTER_GOTO(klass_id, klass, err_class); const op_type_funcs *func = _vtable_func_get (obj->vtable, klass->base_id + klass->ops_count); @@ -1489,11 +1489,11 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id) (tdata->cache.klass == klass_id)) { isa = tdata->cache.isa; - goto shared_ok; + goto done; } - EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE); - EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE); + EO_OBJ_POINTER_GOTO(eo_id, obj, err_shared_obj); + EO_CLASS_POINTER_GOTO(klass_id, klass, err_shared_class); const op_type_funcs *func = _vtable_func_get (obj->vtable, klass->base_id + klass->ops_count); @@ -1503,10 +1503,21 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id) // Currently implemented by reusing the LAST op id. Just marking it with // _eo_class_isa_func. isa = tdata->cache.isa = (func && (func->func == _eo_class_isa_func)); -shared_ok: +done: eina_lock_release(&(_eo_table_data_shared_data->obj_lock)); } return isa; + +err_shared_class: + _EO_POINTER_ERR("Class (%p) is an invalid ref.", klass_id); +err_shared_obj: + eina_lock_release(&(_eo_table_data_shared_data->obj_lock)); + return EINA_FALSE; + +err_class: + _EO_POINTER_ERR("Class (%p) is an invalid ref.", klass_id); +err_obj: + return EINA_FALSE; } EAPI Eo * diff --git a/src/lib/eo/eo_ptr_indirection.h b/src/lib/eo/eo_ptr_indirection.h index 2d2c28c9f1..82c29136f5 100644 --- a/src/lib/eo/eo_ptr_indirection.h +++ b/src/lib/eo/eo_ptr_indirection.h @@ -13,26 +13,39 @@ void _eo_pointer_error(const char *msg); #define _EO_POINTER_ERR(fmt, ptr) \ do { char buf[256]; sprintf(buf, fmt, ptr); _eo_pointer_error(buf); } while (0) -#define EO_OBJ_POINTER(obj_id, obj) \ - _Eo_Object *obj = NULL; \ - do { \ - obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ +#define EO_OBJ_POINTER(obj_id, obj) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ } while (0) -#define EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, ret) \ - _Eo_Object *obj; \ - do { \ - obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ - if (!obj) return (ret); \ +#define EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, ret) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!obj) return (ret); \ } while (0) -#define EO_OBJ_POINTER_RETURN(obj_id, obj) \ - _Eo_Object *obj; \ - do { \ - obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ - if (!obj) return; \ +#define EO_OBJ_POINTER_RETURN(obj_id, obj) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!obj) return; \ } while (0) +#define EO_OBJ_POINTER_GOTO(obj_id, obj, label) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!obj) goto label; \ + } while (0) + +#define EO_CLASS_POINTER(klass_id, klass) \ + _Efl_Class *klass; \ + do { \ + klass = _eo_class_pointer_get(klass_id); \ + } while (0) + #define EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, ret) \ _Efl_Class *klass; \ do { \ @@ -53,19 +66,26 @@ void _eo_pointer_error(const char *msg); } \ } while (0) +#define EO_CLASS_POINTER_GOTO(klass_id, klass, label) \ + _Efl_Class *klass; \ + do { \ + klass = _eo_class_pointer_get(klass_id); \ + if (!klass) goto label; \ + } while (0) + #define EO_OBJ_DONE(obj_id) \ _eo_obj_pointer_done((Eo_Id)obj_id) #else -#define EO_OBJ_POINTER(obj_id, obj) \ - _Eo_Object *obj = NULL; \ - do { \ - obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ - if (obj && \ - !EINA_MAGIC_CHECK((Eo_Header *) obj, EO_EINA_MAGIC)) { \ - EINA_MAGIC_FAIL((Eo_Header *) obj, EO_EINA_MAGIC); \ - } \ +#define EO_OBJ_POINTER(obj_id, obj) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (obj && \ + !EINA_MAGIC_CHECK((Eo_Header *) obj, EO_EINA_MAGIC)) { \ + EINA_MAGIC_FAIL((Eo_Header *) obj, EO_EINA_MAGIC); \ + } \ } while (0) #define EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, ret) \ @@ -84,6 +104,24 @@ void _eo_pointer_error(const char *msg); EO_MAGIC_RETURN((Eo_Header *) obj, EO_EINA_MAGIC); \ } while (0) +#define EO_OBJ_POINTER_GOTO(obj_id, obj, label) \ + _Eo_Object *obj; \ + do { \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!obj || \ + !EINA_MAGIC_CHECK((Eo_Header *) obj, EO_EINA_MAGIC)) goto label; \ + } while (0) + +#define EO_CLASS_POINTER(klass_id, klass) \ + _Efl_Class *klass; \ + do { \ + klass = _eo_class_pointer_get(klass_id); \ + if (klass && \ + !EINA_MAGIC_CHECK((Eo_Header *) klas, EO_CLASS_EINA_MAGIC)) { \ + EO_MAGIC_FAIL((Eo_Header *) klass, EO_CLASS_EINA_MAGIC); \ + } \ + } while (0) + #define EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, ret) \ _Efl_Class *klass; \ do { \ @@ -100,6 +138,15 @@ void _eo_pointer_error(const char *msg); EO_MAGIC_RETURN((Eo_Header *) klass, EO_CLASS_EINA_MAGIC); \ } while (0) +#define EO_CLASS_POINTER_GOTO(klass_id, klass, label) \ + _Efl_Class *klass; \ + do { \ + klass = _eo_class_pointer_get(klass_id); \ + if (!klass) goto label; \ + if (klass && \ + !EINA_MAGIC_CHECK((Eo_Header *) klas, EO_CLASS_EINA_MAGIC)) { \ + } while (0) + #define EO_OBJ_DONE(obj_id) #endif