Array alignment bug

Richard Hult richard@imendio.com
Mon, 22 Dec 2003 02:45:06 +0100


--=-g+RP0GWI2nZ87W4U0r51
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi,

Attaching a patch that aligns the array data properly for 64-bit types.
Without the patch, arrays of int64/uint64/double fail to validate. It
managed to slip through the tests since the array length happened to end
up being aligned to 8 bytes for that particular message, which made the
array data being aligned to 8 bytes as well.

Regards,
Richard

-- 
Richard Hult                    richard@imendio.com
Imendio                         http://www.imendio.com

--=-g+RP0GWI2nZ87W4U0r51
Content-Disposition: attachment; filename=align.diff
Content-Type: text/x-patch; name=align.diff; charset=iso-8859-15
Content-Transfer-Encoding: 7bit

Index: dbus/dbus-marshal.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal.c,v
retrieving revision 1.47
diff -u -b -B -p -r1.47 dbus-marshal.c
--- dbus/dbus-marshal.c	2 Dec 2003 10:44:21 -0000	1.47
+++ dbus/dbus-marshal.c	22 Dec 2003 01:00:20 -0000
@@ -697,6 +697,9 @@ marshal_8_octets_array (DBusString      
   if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
     goto error;
 
+  if (!_dbus_string_align_length (str, 8))
+    goto error;
+  
   array_start = _dbus_string_get_length (str);
   
   if (!_dbus_string_append_len (str, (const unsigned char*) value,
@@ -1248,6 +1251,8 @@ demarshal_8_octets_array (const DBusStri
       return TRUE;
     }
 
+  pos = _DBUS_ALIGN_VALUE (pos, 8);
+  
   if (!_dbus_string_copy_data_len (str, (char**) &retval,
                                    pos, byte_len))
     return FALSE;
@@ -1661,10 +1666,20 @@ _dbus_marshal_get_arg_end_pos (const DBu
     case DBUS_TYPE_ARRAY:
       {
 	int len;
+	int array_type;
+
+	/* The message has already been validated here so we know that there is
+	 * a type at pos - 1.
+	 */
+	_dbus_marshal_validate_type (str, pos - 1, &array_type, NULL);
 
 	/* Demarshal the length  */
 	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
 	
+	if (array_type == DBUS_TYPE_INT64 || array_type == DBUS_TYPE_UINT64 ||
+	    array_type == DBUS_TYPE_DOUBLE)
+	  pos = _DBUS_ALIGN_VALUE (pos, 8);
+	
 	*end_pos = pos + len;
       }
       break;
@@ -2118,6 +2135,10 @@ _dbus_marshal_validate_arg (const DBusSt
         if (len < 0)
           return FALSE;
 
+	if (array_type == DBUS_TYPE_INT64 || array_type == DBUS_TYPE_UINT64 ||
+	    array_type == DBUS_TYPE_DOUBLE)
+	  pos = _DBUS_ALIGN_VALUE (pos, 8);
+		
         if (len > _dbus_string_get_length (str) - pos)
           {
             _dbus_verbose ("array length outside length of the message\n");

--=-g+RP0GWI2nZ87W4U0r51--