From cae939e2085f4c4ec4961f9815e1a270ee196691 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 18 Jul 2016 17:44:51 +0900 Subject: [PATCH] eo: Fix leak in eo_override and allow NULL to reset eo_override would leak the vtable if called multiple times, this fixes that. Also, it is now possible to revert back to the original class' vtable by passing in { NULL, 0 } I believe it is thus possible to incrementally override more functions on an object. Absolutely not recommended, but should work. But it is not possible to selectively revert back to the original class implementation on a single method. Use eo_super for that, or revert back the entire object overrides. PS: Is it normal that we pass in a struct? We never do that in EFL... --- src/lib/eo/eo.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index cb6776e80b..014d859e78 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1343,9 +1343,23 @@ eo_override(Eo *eo_id, Eo_Ops ops) EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE); EO_CLASS_POINTER_RETURN_VAL(EO_OVERRIDE_CLASS, klass, EINA_FALSE); Eo_Vtable *previous = obj->vtable; - obj->vtable = calloc(1, sizeof(*obj->vtable)); - _vtable_init(obj->vtable, previous->size); - _vtable_copy_all(obj->vtable, previous); + + if (!ops.descs) + { + if (obj->vtable != &obj->klass->vtable) + { + free(obj->vtable); + obj->vtable = (Eo_Vtable *) &obj->klass->vtable; + } + return EINA_TRUE; + } + + if (obj->vtable == &obj->klass->vtable) + { + obj->vtable = calloc(1, sizeof(*obj->vtable)); + _vtable_init(obj->vtable, previous->size); + _vtable_copy_all(obj->vtable, previous); + } if (!_eo_class_funcs_set(obj->vtable, &ops, obj->klass, klass, EINA_TRUE)) {