Bugfix, GVariant: no padding in root-level tuples 67/92167/2 accepted/tizen/common/20161017.170021 accepted/tizen/ivi/20161017.013624 accepted/tizen/mobile/20161017.013558 accepted/tizen/tv/20161017.013608 accepted/tizen/wearable/20161017.013616 submit/tizen/20161014.114439
authorAdrian Szyndela <adrian.s@samsung.com>
Thu, 13 Oct 2016 13:04:10 +0000 (15:04 +0200)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 14 Oct 2016 08:52:55 +0000 (10:52 +0200)
Change-Id: If84df57e9985f484e3c3c63854df5ff666cc1794

dbus/dbus-marshal-gvariant.c

index ef0f88b..ebd07fe 100644 (file)
@@ -34,6 +34,9 @@
 /** Static #DBusString containing the signature of a message header */
 _DBUS_STRING_DEFINE_STATIC(_dbus_header_gvariant_signature_str, DBUS_HEADER_GVARIANT_SIGNATURE);
 
+static int
+_dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, int *alignment, int depth);
+
 #define FIELD_ID_SIZE sizeof(dbus_uint64_t)
 
 const DBusString *
@@ -789,7 +792,24 @@ _dbus_message_finalize_gvariant (DBusMessage *message, dbus_bool_t remove_signat
      * and delete the field
      */
     const char *sig_ptr = _dbus_string_get_const_data (type_str) + type_pos;
+    int alignment;
+    int fixed_size;
+
     _dbus_string_init_const (&str, sig_ptr);
+
+    /* There is a special case for structs of fixed size. They need to have size
+     * which is a multiply of required alignment.
+     * The root struct must be finalized just before adding signature and locking the message.
+     * Luckily, fixed size means that there are no offsets in the message body.
+     */
+    fixed_size = _dbus_reader_get_signature_fixed_size (type_str, &type_pos, &alignment, 1);
+    if (fixed_size > 0)
+    {
+      int current_length = _dbus_string_get_length (&message->body);
+      int diff = _DBUS_ALIGN_VALUE (current_length, alignment) - current_length;
+      if (diff > 0)
+        _dbus_string_insert_bytes (&message->body, current_length, diff, 0);
+    }
   }
   else
   {
@@ -845,17 +865,18 @@ update_size (int current_size, int size_of_element, int *alignment, int new_alig
 }
 
 static int
-_dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, int *alignment)
+_dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, int *alignment,
+                                       int depth)
 {
   int res = 0;
-  int depth = 0;
   int current_alignment = 1;
   dbus_bool_t variable = FALSE;
+  int length = _dbus_string_get_length (signature);
 
   char c = _dbus_string_get_byte (signature, *pos);
   if (c == DBUS_STRUCT_BEGIN_CHAR || c == DBUS_DICT_ENTRY_BEGIN_CHAR)
   {
-    depth = 1;
+    depth++;
     (*pos)++;
   }
 
@@ -888,7 +909,7 @@ _dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, in
       case DBUS_DICT_ENTRY_BEGIN_CHAR:
         {
           int alignment_recursive;
-          int res_recursive = _dbus_reader_get_signature_fixed_size (signature, pos, &alignment_recursive);
+          int res_recursive = _dbus_reader_get_signature_fixed_size (signature, pos, &alignment_recursive, 0);
           if (res_recursive == 0)
             variable = TRUE;   /* variable size detected */
 
@@ -904,7 +925,7 @@ _dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, in
         {
           int alignment_recursive;
           int recursive_pos = *pos + 1;
-          int res_recursive = _dbus_reader_get_signature_fixed_size (signature, &recursive_pos, &alignment_recursive);
+          int res_recursive = _dbus_reader_get_signature_fixed_size (signature, &recursive_pos, &alignment_recursive, 0);
 
           variable = TRUE;       /* variable size detected */
 
@@ -915,11 +936,14 @@ _dbus_reader_get_signature_fixed_size (const DBusString *signature, int *pos, in
           *pos = recursive_pos - 1;
         }
         break;
+         case DBUS_TYPE_INVALID:
+               depth = 0;
+               break;
       default:
         variable = TRUE;       /* variable size detected */
     }
     (*pos)++;
-  } while (depth > 0);
+  } while (depth > 0 && *pos < length);
 
   /* we want to point it to the last character, to allow upper instance to skip it */
   (*pos)--;
@@ -934,13 +958,13 @@ int
 _dbus_reader_get_type_fixed_size (DBusTypeReader *reader, int *alignment)
 {
   int pos = reader->type_pos;
-  return _dbus_reader_get_signature_fixed_size (reader->type_str, &pos, alignment);
+  return _dbus_reader_get_signature_fixed_size (reader->type_str, &pos, alignment, 0);
 }
 
 int
 _dbus_type_gvariant_get_fixed_size (const DBusString *type_str, int type_pos, int *alignment)
 {
-  return _dbus_reader_get_signature_fixed_size (type_str, &type_pos, alignment);
+  return _dbus_reader_get_signature_fixed_size (type_str, &type_pos, alignment, 0);
 }
 
 static int