eldbus: fix _eldbus_message_iter_arguments_vget
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Fri, 2 Oct 2015 07:13:48 +0000 (09:13 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Fri, 2 Oct 2015 07:14:29 +0000 (09:14 +0200)
Summary:
there is a problem with _eldbus_message_iter_arguments_vget.

Assume: We have a array of type y, there are 3 elements in the array.

Lets say we are iterating with

printf("%c", dbus_message_iter_get_arg_type(iter));

and

dbus_message_iter_next(iter);

throuw the iter.

You will see that this will output yyy. As we are having 3 times v.
While the signature of the message iterator is y.

If you now call eldbus_message_iter_arguments_get(message, "y", &cont)
it will return false, with the errormessage in line 766, reason for this
is that the type of the signature iterator differs from the message
iterator. Because of the upper example.
So all in all: The signature given to the method has not to be equal to
the signature of the message iterator, it has to be equal to the
iterated signature, which cannot be found easily with the eldbus api.

The solution is to only iterate in the message iterator that long until
the signature iterator is at the end, if the type differs in this
region, give a error and return false. Otherwise return true.

The sad thing about this is that it is a behaviour break, but the
behaviour is borked, so its a fix.

I tested this over a week now, without any problem in efl/elm/e.

Reviewers: stefan_schmidt, zmike

Reviewed By: stefan_schmidt

Subscribers: zmike, ceolin, simotek, DaveMDS, cedric

Projects: #efl

Differential Revision: https://phab.enlightenment.org/D3074

src/lib/eldbus/eldbus_message.c

index 03b8d64..54cba80 100644 (file)
@@ -677,8 +677,19 @@ get_basic(char type, DBusMessageIter *iter, va_list *vl)
 EAPI Eina_Bool
 eldbus_message_iter_fixed_array_get(Eldbus_Message_Iter *iter, int signature, void *value, int *n_elements)
 {
+   int iter_type;
+
    ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
    EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(n_elements, EINA_FALSE);
+
+   iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
+
+   if (iter_type == DBUS_TYPE_INVALID)
+     {
+        *n_elements = 0;
+        return EINA_TRUE;
+     }
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL(
         (dbus_message_iter_get_arg_type(&iter->dbus_iterator) == signature),
@@ -761,9 +772,12 @@ _eldbus_message_iter_arguments_vget(Eldbus_Message_Iter *iter, const char *signa
      {
         int sig_type = dbus_signature_iter_get_current_type(&sig_iter);
 
+        if (sig_type == DBUS_TYPE_INVALID)
+          break;
+
         if (sig_type != iter_type)
           {
-             ERR("Type in iterator different of signature");
+             ERR("Type in iterator different of signature expected:%c got %c", iter_type, sig_type);
              return EINA_FALSE;
           }