tasn pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=d889da6b12e6123073edb54d766c9af1fc6db822

commit d889da6b12e6123073edb54d766c9af1fc6db822
Author: Tom Hacohen <t...@stosb.com>
Date:   Tue Sep 29 00:45:34 2015 +0100

    Eo legacy events: Fix broken callback comparison
    
    Commit 37f84b7e966372384e2dfe5d191a6f907a17962e introduced a few changes
    to the callback matching mechanism that made it so sometimes callbacks
    would be triggered for the wrong events. The problem was there because
    of the support for legacy events that forces to do string comparison
    instead of the usual pointer comparison. We should only do string
    comparison when we are certain one of the callbacks is a legacy
    generated one.
    
    Regression tests will follow tomorrow. Way too late here for that.
    
    Thanks to cedric for reporting.
---
 src/lib/eo/Eo.h                      |  2 ++
 src/lib/eo/eo_base_class.c           | 39 ++++++++++++++++++++++++++++++++----
 src/tests/eo/suite/eo_test_general.c |  4 ++--
 3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 3f551f4..66be6ff 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -919,6 +919,8 @@ typedef void (*eo_key_data_free_func)(void *);
 
 /**
  * Don't use.
+ * The values of the returned event structure are also internal, don't assume
+ * anything about them.
  * @internal
  */
 EAPI const Eo_Event_Description 
*eo_base_legacy_only_event_description_get(const char *_event_name);
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index f85aa4e..f0a4030 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -401,11 +401,16 @@ _wref_destruct(Eo_Base_Data *pd)
 
 /* XXX: Legacy support, remove when legacy is dead. */
 static Eina_Hash *_legacy_events_hash = NULL;
+#define _LEGACY_EVENT_FIRST_CHAR 1
 
 EAPI const Eo_Event_Description *
 eo_base_legacy_only_event_description_get(const char *_event_name)
 {
-   Eina_Stringshare *event_name = eina_stringshare_add(_event_name);
+   char buf[1024];
+   buf[0] = _LEGACY_EVENT_FIRST_CHAR; /* Encode it's a legacy event */
+   strncpy(buf + 1, _event_name, sizeof(buf) - 1);
+   buf[sizeof(buf) - 1] = '\0';
+   Eina_Stringshare *event_name = eina_stringshare_add(buf);
    Eo_Event_Description *event_desc = eina_hash_find(_legacy_events_hash, 
event_name);
    if (!event_desc)
      {
@@ -421,6 +426,26 @@ eo_base_legacy_only_event_description_get(const char 
*_event_name)
    return event_desc;
 }
 
+static Eina_Bool
+_legacy_event_desc_is(const Eo_Event_Description *desc)
+{
+   return (desc->name[0] == _LEGACY_EVENT_FIRST_CHAR);
+}
+
+/* Also supports non legacy. */
+static const char *
+_legacy_event_desc_name_get(const Eo_Event_Description *desc)
+{
+   if (_legacy_event_desc_is(desc))
+     {
+        return desc->name + 1;
+     }
+   else
+     {
+        return desc->name;
+     }
+}
+
 static void
 _legacy_events_hash_free_cb(void *_desc)
 {
@@ -641,13 +666,19 @@ _cb_desc_match(const Eo_Event_Description *a, const 
Eo_Event_Description *b)
    if (!a)
       return EINA_FALSE;
 
-   if (a == b)
+   if (_legacy_event_desc_is(a) && _legacy_event_desc_is(b))
+     {
+        return (a->name == b->name);
+     }
+   else if (_legacy_event_desc_is(a) || _legacy_event_desc_is(b))
      {
-        return EINA_TRUE;
+        const char *aname = _legacy_event_desc_name_get(a);
+        const char *bname = _legacy_event_desc_name_get(b);
+        return !strcmp(aname, bname);
      }
    else
      {
-        return !strcmp(a->name, b->name);
+        return (a == b);
      }
 }
 
diff --git a/src/tests/eo/suite/eo_test_general.c 
b/src/tests/eo/suite/eo_test_general.c
index ccd6af2..b483a80 100644
--- a/src/tests/eo/suite/eo_test_general.c
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -125,12 +125,12 @@ START_TEST(eo_signals)
      {
         const Eo_Event_Description *a_desc = 
eo_base_legacy_only_event_description_get("a,changed");
         fail_if(!a_desc);
-        ck_assert_str_eq(a_desc->name, "a,changed");
+        ck_assert_str_eq(a_desc->name, "\x01" "a,changed");
         fail_if(a_desc == EV_A_CHANGED);
 
         const Eo_Event_Description *bad_desc = 
eo_base_legacy_only_event_description_get("bad");
         fail_if(!bad_desc);
-        ck_assert_str_eq(bad_desc->name, "bad");
+        ck_assert_str_eq(bad_desc->name, "\x01" "bad");
 
         /* Call Eo event with legacy and non-legacy callbacks. */
         _eo_signals_cb_current = 0;

-- 


Reply via email to