diff options
| author | Alexander Larsson <alexl@redhat.com> | 2003-04-10 11:04:24 +0000 | 
|---|---|---|
| committer | Alexander Larsson <alexl@redhat.com> | 2003-04-10 11:04:24 +0000 | 
| commit | e84c3a03b3be9cfc351ca8e0b9b935cca455e672 (patch) | |
| tree | 55faf4c7cdead5cb59e8c36c3e8fe136673b89cf | |
| parent | 51781f541094a4936d47119cd62682e0431c41e9 (diff) | |
2003-04-10  Alexander Larsson  <alexl@redhat.com>
	* dbus/dbus-marshal.[ch]:
	Add array_type_pos argument to _dbus_marshal_validate_arg.
	Let you pass a NULL end_pos to _dbus_marshal_validate_type.
	* dbus/dbus-message.[ch]:
	Multi-dimensional arrays have full type specification in the
	outermost array. Iter code re-arranged to handle this.
	Added some more iter tests.
	* doc/dbus-specification.sgml:
	Add me to authors.
	Remove old FIXME.
	Update new array encoding description.
	Correct DBUS_SERVICE_FLAGS_REPLACE_EXISTING description.
	* test/data/invalid-messages/array-with-mixed-types.message:
	* test/data/valid-messages/array-of-array-of-uint32.message:
	Change to the new array format.
	* test/data/invalid-messages/too-short-dict.message:
	Fix bug in test.
	* test/data/valid-messages/recursive-types.message:
	Fix up and extend test.
| -rw-r--r-- | ChangeLog | 27 | ||||
| -rw-r--r-- | dbus/dbus-marshal.c | 55 | ||||
| -rw-r--r-- | dbus/dbus-marshal.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 438 | ||||
| -rw-r--r-- | dbus/dbus-message.h | 1 | ||||
| -rw-r--r-- | doc/dbus-specification.sgml | 36 | ||||
| -rw-r--r-- | test/data/invalid-messages/array-with-mixed-types.message | 6 | ||||
| -rw-r--r-- | test/data/invalid-messages/too-short-dict.message | 3 | ||||
| -rw-r--r-- | test/data/valid-messages/array-of-array-of-uint32.message | 3 | ||||
| -rw-r--r-- | test/data/valid-messages/recursive-types.message | 79 | 
10 files changed, 456 insertions, 193 deletions
| @@ -1,3 +1,30 @@ +2003-04-10  Alexander Larsson  <alexl@redhat.com> + +	* dbus/dbus-marshal.[ch]: +	Add array_type_pos argument to _dbus_marshal_validate_arg. +	Let you pass a NULL end_pos to _dbus_marshal_validate_type. +	 +	* dbus/dbus-message.[ch]: +	Multi-dimensional arrays have full type specification in the +	outermost array. Iter code re-arranged to handle this. +	Added some more iter tests. +	 +	* doc/dbus-specification.sgml: +	Add me to authors. +	Remove old FIXME. +	Update new array encoding description. +	Correct DBUS_SERVICE_FLAGS_REPLACE_EXISTING description. +	 +	* test/data/invalid-messages/array-with-mixed-types.message: +	* test/data/valid-messages/array-of-array-of-uint32.message: +	Change to the new array format. +	 +	* test/data/invalid-messages/too-short-dict.message: +	Fix bug in test. +	 +	* test/data/valid-messages/recursive-types.message: +	Fix up and extend test. +  2003-04-10  Havoc Pennington  <hp@pobox.com>  	* bus/dispatch.c: lots of fixes diff --git a/dbus/dbus-marshal.c b/dbus/dbus-marshal.c index b1eb6fc7..02343174 100644 --- a/dbus/dbus-marshal.c +++ b/dbus/dbus-marshal.c @@ -1027,8 +1027,8 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,        {  	int len; -	/* Demarshal the length (element type is at pos + 0 */ -	len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos); +	/* Demarshal the length  */ +	len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);  	*end_pos = pos + len;        } @@ -1169,7 +1169,8 @@ _dbus_marshal_validate_type   (const DBusString *str,    if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)      {        *type = *data; -      *end_pos = pos + 1; +      if (end_pos != NULL) +	*end_pos = pos + 1;        return TRUE;      } @@ -1194,6 +1195,8 @@ _dbus_marshal_validate_type   (const DBusString *str,   * @param byte_order the byte order to use   * @param depth current recursion depth, to prevent excessive recursion   * @param type the type of the argument + * @param array_type_pos the position of the current array type, or + *        -1 if not in an array   * @param pos the pos where the arg starts   * @param end_pos pointer where the position right   * after the end position will follow @@ -1204,6 +1207,7 @@ _dbus_marshal_validate_arg (const DBusString *str,                              int	              byte_order,                              int               depth,  			    int               type, +			    int               array_type_pos,                              int               pos,                              int              *end_pos)  { @@ -1340,21 +1344,38 @@ _dbus_marshal_validate_arg (const DBusString *str,  	int end;  	int array_type; -	if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos)) +	if (array_type_pos == -1) +	  { +	    array_type_pos = pos; + +	    do +	      { +		if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos)) +		  { +		    _dbus_verbose ("invalid array type\n"); +		    return FALSE; +		  } +		 +		/* NIL values take up no space, so you couldn't iterate over an array of them. +		 * array of nil seems useless anyway; the useful thing might be array of +		 * (nil OR string) but we have no framework for that. +		 */ +		if (array_type == DBUS_TYPE_NIL) +		  { +		    _dbus_verbose ("array of NIL is not allowed\n"); +		    return FALSE; +		  } +	      } +	    while (array_type == DBUS_TYPE_ARRAY); +	  } +	else +	  array_type_pos++; + +	if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))  	  {  	    _dbus_verbose ("invalid array type\n");  	    return FALSE;  	  } - -        /* NIL values take up no space, so you couldn't iterate over an array of them. -         * array of nil seems useless anyway; the useful thing might be array of -         * (nil OR string) but we have no framework for that. -         */ -        if (array_type == DBUS_TYPE_NIL) -          { -            _dbus_verbose ("array of NIL is not allowed\n"); -            return FALSE; -          }  	len = demarshal_and_validate_len (str, byte_order, pos, &pos);          if (len < 0) @@ -1371,7 +1392,7 @@ _dbus_marshal_validate_arg (const DBusString *str,  	while (pos < end)  	  {  	    if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, -					     array_type, pos, &pos)) +					     array_type, array_type_pos, pos, &pos))  	      return FALSE;  	  } @@ -1417,7 +1438,7 @@ _dbus_marshal_validate_arg (const DBusString *str,  	  {  	    /* Validate name */  	    if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, -					     DBUS_TYPE_STRING, pos, &pos)) +					     DBUS_TYPE_STRING, -1, pos, &pos))  	      return FALSE;  	    if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos)) @@ -1428,7 +1449,7 @@ _dbus_marshal_validate_arg (const DBusString *str,  	    /* Validate element */  	    if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1, -					     dict_type, pos, &pos)) +					     dict_type, -1, pos, &pos))  	      return FALSE;  	  } diff --git a/dbus/dbus-marshal.h b/dbus/dbus-marshal.h index 81ff6f50..53b9b7b3 100644 --- a/dbus/dbus-marshal.h +++ b/dbus/dbus-marshal.h @@ -186,6 +186,7 @@ dbus_bool_t _dbus_marshal_validate_arg    (const DBusString *str,                                             int               depth,                                             int               byte_order,  					   int               type, +					   int               array_type_pos,                                             int               pos,                                             int              *end_pos); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 6bddc3f0..64cfb864 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -133,10 +133,13 @@ struct DBusMessageRealIter    int pos; /**< Current position in the string */    int end; /**< position right after the container */ -  int container_type; /**< type of the items in the container (used for arrays) */    int container_start; /**< offset of the start of the container */    int container_length_pos; /**< offset of the length of the container */ +      int wrote_dict_key; /**< whether we wrote the dict key for the current dict element */ + +  int array_type_pos; /**< pointer to the position of the array element type */ +  int array_type_done; /**< TRUE if the array type is fully finished */  };  /** @@ -1571,10 +1574,10 @@ dbus_message_iter_init (DBusMessage *message,    real->pos = 0;    real->end = _dbus_string_get_length (&message->body); -  real->container_type = 0;    real->container_start = 0;    real->container_length_pos = 0;    real->wrote_dict_key = 0; +  real->array_type_pos = 0;  }  static void @@ -1587,6 +1590,21 @@ dbus_message_iter_check (DBusMessageRealIter *iter)  }  static int +skip_array_type (DBusMessageRealIter *iter, int pos) +{ +  const char *data; + +  do +    { +      data = _dbus_string_get_const_data_len (&iter->message->body, +					      pos++, 1); +    } +  while (*data == DBUS_TYPE_ARRAY); +   +  return pos; +} + +static int  dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)  {    const char *data; @@ -1602,12 +1620,17 @@ dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)        else  	*type = DBUS_TYPE_INVALID; -      return iter->pos + 1; +      return skip_array_type (iter, iter->pos);      case DBUS_MESSAGE_ITER_TYPE_ARRAY: -      *type = iter->container_type; -      return iter->pos; +      data = _dbus_string_get_const_data_len (&iter->message->body, +					      iter->array_type_pos, 1); +      if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST) +	*type = *data; +      else +	*type = DBUS_TYPE_INVALID; +      return iter->pos;      case DBUS_MESSAGE_ITER_TYPE_DICT:        /* Get the length of the string */ @@ -1615,13 +1638,16 @@ dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type)  				    iter->message->byte_order,  				    iter->pos, &pos);        pos = pos + len + 1; +        data = _dbus_string_get_const_data_len (&iter->message->body,  					      pos, 1);        if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)  	*type = *data;        else  	*type = DBUS_TYPE_INVALID; -      return pos + 1; + +      return skip_array_type (iter, pos); +            default:        _dbus_assert_not_reached ("Invalid iter type");        break; @@ -1716,6 +1742,48 @@ dbus_message_iter_get_arg_type (DBusMessageIter *iter)    return type;  } +static int +iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos) +{ +  const char *data; +  int _array_type_pos; +  int len, pos; +   +  switch (iter->type) +    { +    case DBUS_MESSAGE_ITER_TYPE_MESSAGE: +      _array_type_pos = iter->pos + 1; +      break; +    case DBUS_MESSAGE_ITER_TYPE_ARRAY: +      _array_type_pos = iter->array_type_pos + 1; +      break; +    case DBUS_MESSAGE_ITER_TYPE_DICT: +      /* Get the length of the string */ +      len = _dbus_demarshal_uint32 (&iter->message->body, +				    iter->message->byte_order, +				    iter->pos, &pos); +      pos = pos + len + 1; +      data = _dbus_string_get_const_data_len (&iter->message->body, +					      pos + 1, 1); +      _array_type_pos = pos + 1; +      break; +    default: +      _dbus_assert_not_reached ("wrong iter type"); +      return DBUS_TYPE_INVALID; +    } + +  if (array_type_pos != NULL) +    *array_type_pos = _array_type_pos; +   +  data = _dbus_string_get_const_data_len (&iter->message->body, +					  _array_type_pos, 1); +  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST) +    return  *data; +   +  return DBUS_TYPE_INVALID; +} + +  /**   * Returns the element type of the array that the   * message iterator points at. Note that you need @@ -1730,7 +1798,6 @@ dbus_message_iter_get_array_type (DBusMessageIter *iter)  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -1741,13 +1808,7 @@ dbus_message_iter_get_array_type (DBusMessageIter *iter)    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); -  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST) -    return *data; -   -  return DBUS_TYPE_INVALID; +  return iter_get_array_type (real, NULL);  } @@ -1970,9 +2031,8 @@ dbus_message_iter_init_array_iterator (DBusMessageIter *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter; -  int type, pos, len_pos, len; +  int type, pos, len_pos, len, array_type_pos;    int _array_type; -  const char *data;    dbus_message_iter_check (real); @@ -1980,17 +2040,11 @@ dbus_message_iter_init_array_iterator (DBusMessageIter *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); -  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST) -    _array_type = *data; -  else -    return FALSE; - -  len_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)); +  _array_type = iter_get_array_type (real, &array_type_pos); +   +  len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));    len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order, -				pos + 1, &pos); +				pos, &pos);    array_real->parent_iter = real;    array_real->message = real->message; @@ -2000,11 +2054,12 @@ dbus_message_iter_init_array_iterator (DBusMessageIter *iter,    array_real->pos = pos;    array_real->end = pos + len; -  array_real->container_type = _array_type;    array_real->container_start = pos;    array_real->container_length_pos = len_pos;    array_real->wrote_dict_key = 0; - +  array_real->array_type_pos = array_type_pos; +  array_real->array_type_done = TRUE; +      if (array_type != NULL)      *array_type = _array_type; @@ -2047,7 +2102,6 @@ dbus_message_iter_init_dict_iterator (DBusMessageIter *iter,    dict_real->pos = pos;    dict_real->end = pos + len; -  dict_real->container_type = 0;    dict_real->container_start = pos;    dict_real->container_length_pos = len_pos;    dict_real->wrote_dict_key = 0; @@ -2072,7 +2126,6 @@ dbus_message_iter_get_byte_array (DBusMessageIter  *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2080,14 +2133,12 @@ dbus_message_iter_get_byte_array (DBusMessageIter  *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); +  type = iter_get_array_type (real, NULL); -  _dbus_assert (*data == DBUS_TYPE_BYTE); +  _dbus_assert (type == DBUS_TYPE_BYTE);    if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order, -				   pos + 1, NULL, value, len)) +				   pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2110,7 +2161,6 @@ dbus_message_iter_get_boolean_array (DBusMessageIter   *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2118,14 +2168,12 @@ dbus_message_iter_get_boolean_array (DBusMessageIter   *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); +  type = iter_get_array_type (real, NULL); -  _dbus_assert (*data == DBUS_TYPE_BOOLEAN); +  _dbus_assert (type == DBUS_TYPE_BOOLEAN);    if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order, -				   pos + 1, NULL, value, len)) +				   pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2148,7 +2196,6 @@ dbus_message_iter_get_int32_array  (DBusMessageIter *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2156,14 +2203,12 @@ dbus_message_iter_get_int32_array  (DBusMessageIter *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); - -  _dbus_assert (*data == DBUS_TYPE_INT32); +  type = iter_get_array_type (real, NULL); +   +  _dbus_assert (type == DBUS_TYPE_INT32);    if (!_dbus_demarshal_int32_array (&real->message->body, real->message->byte_order, -				    pos + 1, NULL, value, len)) +				    pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2186,7 +2231,6 @@ dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2194,14 +2238,11 @@ dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); - -  _dbus_assert (*data == DBUS_TYPE_UINT32); +  type = iter_get_array_type (real, NULL); +  _dbus_assert (type == DBUS_TYPE_UINT32);    if (!_dbus_demarshal_uint32_array (&real->message->body, real->message->byte_order, -				    pos + 1, NULL, value, len)) +				    pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2224,7 +2265,6 @@ dbus_message_iter_get_double_array  (DBusMessageIter *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2232,14 +2272,11 @@ dbus_message_iter_get_double_array  (DBusMessageIter *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); - -  _dbus_assert (*data == DBUS_TYPE_DOUBLE); +  type = iter_get_array_type (real, NULL); +  _dbus_assert (type == DBUS_TYPE_DOUBLE);    if (!_dbus_demarshal_double_array (&real->message->body, real->message->byte_order, -				     pos + 1, NULL, value, len)) +				     pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2267,7 +2304,6 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,  {    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    int type, pos; -  const char *data;    dbus_message_iter_check (real); @@ -2275,14 +2311,11 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,    _dbus_assert (type == DBUS_TYPE_ARRAY); -  data = _dbus_string_get_const_data_len (&real->message->body, -					  pos, -					  1); - -  _dbus_assert (*data == DBUS_TYPE_STRING); +  type = iter_get_array_type (real, NULL); +  _dbus_assert (type == DBUS_TYPE_STRING);    if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order, -				     pos + 1, NULL, value, len)) +				     pos, NULL, value, len))      return FALSE;    else      return TRUE; @@ -2332,7 +2365,6 @@ dbus_message_append_iter_init (DBusMessage *message,    real->end = _dbus_string_get_length (&real->message->body);    real->pos = real->end; -  real->container_type = 0;    real->container_length_pos = 0;    real->wrote_dict_key = 0;  } @@ -2356,6 +2388,7 @@ static dbus_bool_t  dbus_message_iter_append_type (DBusMessageRealIter *iter,  			       int type)  { +  const char *data;    switch (iter->type)      {      case DBUS_MESSAGE_ITER_TYPE_MESSAGE: @@ -2364,7 +2397,9 @@ dbus_message_iter_append_type (DBusMessageRealIter *iter,        break;      case DBUS_MESSAGE_ITER_TYPE_ARRAY: -      if (type != iter->container_type) +      data = _dbus_string_get_const_data_len (&iter->message->body, +					      iter->array_type_pos, 1); +      if (type != *data)  	{  	  _dbus_warn ("Appended element of wrong type for array\n");  	  return FALSE; @@ -2402,7 +2437,7 @@ dbus_message_iter_update_after_change (DBusMessageRealIter *iter)    /* Set container length */    if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT || -      iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY) +      (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done))      _dbus_marshal_set_uint32 (&iter->message->body,  			      iter->message->byte_order,  			      iter->container_length_pos, @@ -2689,6 +2724,81 @@ dbus_message_iter_append_dict_key (DBusMessageIter *iter,    return TRUE;  } +static dbus_bool_t +array_iter_type_mark_done (DBusMessageRealIter *iter) +{ +  int len_pos; +   +  if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY) +    array_iter_type_mark_done (iter->parent_iter); +  else +    return TRUE; + +  len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body), +			       sizeof (dbus_uint32_t)); + +  /* Empty length for now, backfill later */ +  if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0)) +    { +      _dbus_string_set_length (&iter->message->body, iter->pos); +      return FALSE; +    } + +  iter->container_start = _dbus_string_get_length (&iter->message->body); +  iter->container_length_pos = len_pos; +  iter->array_type_done = TRUE; + +  return TRUE; +} + +static dbus_bool_t +append_array_type (DBusMessageRealIter *real, +		   int                  element_type, +		   dbus_bool_t         *array_type_done, +		   int                 *array_type_pos) +{ +  int existing_element_type; +   +  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +    return FALSE; +   +  if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && +      real->array_type_done) +    { +      existing_element_type = iter_get_array_type (real, array_type_pos); +      if (existing_element_type != element_type) +	{ +	  _dbus_warn ("Appending array of %d, when expecting array of %d\n", +		      element_type, existing_element_type); +	  _dbus_string_set_length (&real->message->body, real->pos); +	  return FALSE; +	} +      if (array_type_done != NULL) +	  *array_type_done = TRUE; +    } +  else +    { +      if (array_type_pos != NULL) +	*array_type_pos = _dbus_string_get_length (&real->message->body); +       +      /* Append element type */ +      if (!_dbus_string_append_byte (&real->message->body, element_type)) +	{ +	  _dbus_string_set_length (&real->message->body, real->pos); +	  return FALSE; +	} + +      if (array_type_done != NULL) +	*array_type_done = element_type != DBUS_TYPE_ARRAY; +       +      if (element_type != DBUS_TYPE_ARRAY && +	  !array_iter_type_mark_done (real)) +	return FALSE; +    } + +  return TRUE; +} +  /**   * Appends an array to the message and initializes an iterator that   * can be used to append to the array. @@ -2706,25 +2816,30 @@ dbus_message_iter_append_array (DBusMessageIter      *iter,    DBusMessageRealIter *real = (DBusMessageRealIter *)iter;    DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter;    int len_pos; +  int array_type_pos; +  dbus_bool_t array_type_done; -  dbus_message_iter_append_check (real); - -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) -    return FALSE; - -  if (!_dbus_string_append_byte (&real->message->body, element_type)) +  if (element_type == DBUS_TYPE_NIL)      { -      _dbus_string_set_length (&real->message->body, real->pos); +      _dbus_warn ("Can't create NIL arrays\n");        return FALSE;      } +   +  dbus_message_iter_append_check (real); + +  if (!append_array_type (real, element_type, &array_type_done, &array_type_pos)) +    return FALSE;    len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t)); -  /* Empty length for now, backfill later */ -  if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0)) +  if (array_type_done)      { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; +      /* Empty length for now, backfill later */ +      if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0)) +	{ +	  _dbus_string_set_length (&real->message->body, real->pos); +	  return FALSE; +	}      }    array_real->parent_iter = real; @@ -2735,10 +2850,11 @@ dbus_message_iter_append_array (DBusMessageIter      *iter,    array_real->pos = _dbus_string_get_length (&real->message->body);    array_real->end = array_real->end; -  array_real->container_type = element_type;    array_real->container_start = array_real->pos;    array_real->container_length_pos = len_pos;    array_real->wrote_dict_key = 0; +  array_real->array_type_done = array_type_done; +  array_real->array_type_pos = array_type_pos;    dbus_message_iter_append_done (array_real); @@ -2784,7 +2900,6 @@ dbus_message_iter_append_dict (DBusMessageIter      *iter,    dict_real->pos = _dbus_string_get_length (&real->message->body);    dict_real->end = dict_real->end; -  dict_real->container_type = 0;    dict_real->container_start = dict_real->pos;    dict_real->container_length_pos = len_pos;    dict_real->wrote_dict_key = 0; @@ -2812,15 +2927,9 @@ dbus_message_iter_append_boolean_array (DBusMessageIter     *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_BOOLEAN, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BOOLEAN)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -2849,15 +2958,9 @@ dbus_message_iter_append_int32_array (DBusMessageIter    *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_INT32, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_INT32)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_int32_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -2886,15 +2989,9 @@ dbus_message_iter_append_uint32_array (DBusMessageIter     *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_UINT32, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_UINT32)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_uint32_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -2923,15 +3020,9 @@ dbus_message_iter_append_double_array (DBusMessageIter *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_DOUBLE, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_DOUBLE)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_double_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -2960,15 +3051,9 @@ dbus_message_iter_append_byte_array (DBusMessageIter     *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_BYTE, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BYTE)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -2997,15 +3082,9 @@ dbus_message_iter_append_string_array (DBusMessageIter *iter,    dbus_message_iter_append_check (real); -  if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) +  if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL))      return FALSE; -  if (!_dbus_string_append_byte (&real->message->body, DBUS_TYPE_BYTE)) -    { -      _dbus_string_set_length (&real->message->body, real->pos); -      return FALSE; -    } -    if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len))      {        _dbus_string_set_length (&real->message->body, real->pos); @@ -3524,7 +3603,7 @@ decode_header_data (const DBusString   *data,  	  return FALSE;  	} -      if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, pos, &new_pos)) +      if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos))          {            _dbus_verbose ("Failed to validate argument to named header field\n");            return FALSE; @@ -3706,7 +3785,7 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader)                if (!_dbus_marshal_validate_arg (&loader->data,                                                 byte_order,                                                 0, -					       type, +					       type, -1,                                                 next_arg,                                                 &next_arg))                  { @@ -3898,8 +3977,10 @@ _dbus_message_loader_get_max_message_size (DBusMessageLoader  *loader)  static void  message_iter_test (DBusMessage *message)  { -  DBusMessageIter iter, dict, array; +  DBusMessageIter iter, dict, array, array2;    char *str; +  dbus_int32_t *our_int_array; +  int array_len;    dbus_message_iter_init (message, &iter); @@ -3976,6 +4057,9 @@ message_iter_test (DBusMessage *message)    if (!dbus_message_iter_next (&iter))      _dbus_assert_not_reached ("Reached end of arguments"); + +  /* dict */ +    if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT)      _dbus_assert_not_reached ("not dict type"); @@ -3993,6 +4077,69 @@ message_iter_test (DBusMessage *message)    if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF)      _dbus_assert_not_reached ("wrong dict entry value"); +  if (!dbus_message_iter_next (&dict)) +    _dbus_assert_not_reached ("reached end of dict"); +   +  /* array of array of int32 (in dict) */ + +  str = dbus_message_iter_get_dict_key (&dict); +  if (str == NULL || strcmp (str, "array") != 0) +    _dbus_assert_not_reached ("wrong dict key"); +  dbus_free (str); +   +  if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY) +    _dbus_assert_not_reached ("Argument type not an array"); + +  if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY) +    _dbus_assert_not_reached ("Array type not array"); + +  if (!dbus_message_iter_init_array_iterator (&dict, &array, NULL)) +    _dbus_assert_not_reached ("Array init failed"); + +  if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY) +    _dbus_assert_not_reached ("Argument type isn't array"); +   +  if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32) +    _dbus_assert_not_reached ("Array type not int32"); +   +  if (!dbus_message_iter_init_array_iterator (&array, &array2, NULL)) +    _dbus_assert_not_reached ("Array init failed"); + +  if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32) +    _dbus_assert_not_reached ("Argument type isn't int32"); + +  if (dbus_message_iter_get_int32 (&array2) != 0x12345678) +    _dbus_assert_not_reached ("Signed integers differ"); + +  if (!dbus_message_iter_next (&array2)) +    _dbus_assert_not_reached ("Reached end of arguments"); + +  if (dbus_message_iter_get_int32 (&array2) != 0x23456781) +    _dbus_assert_not_reached ("Signed integers differ"); + +  if (dbus_message_iter_next (&array2)) +    _dbus_assert_not_reached ("Didn't reached end of arguments"); + +  if (!dbus_message_iter_next (&array)) +    _dbus_assert_not_reached ("Reached end of arguments"); + +  if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32) +    _dbus_assert_not_reached ("Array type not int32"); + +  if (!dbus_message_iter_get_int32_array (&array, +					  &our_int_array, +					  &array_len)) +    _dbus_assert_not_reached ("couldn't get int32 array"); + +  _dbus_assert (array_len == 3); +  _dbus_assert (our_int_array[0] == 0x34567812 && +		our_int_array[1] == 0x45678123 && +		our_int_array[2] == 0x56781234); +  dbus_free (our_int_array); +   +  if (dbus_message_iter_next (&array)) +    _dbus_assert_not_reached ("Didn't reach end of array"); +    if (dbus_message_iter_next (&dict))      _dbus_assert_not_reached ("Didn't reach end of dict"); @@ -4005,6 +4152,7 @@ message_iter_test (DBusMessage *message)    if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE)      _dbus_assert_not_reached ("wrong value after dict"); +      if (dbus_message_iter_next (&iter))      _dbus_assert_not_reached ("Didn't reach end of arguments");  } @@ -4106,7 +4254,7 @@ check_message_handling_type (DBusMessageIter *iter,  		return FALSE;  	      }  	    dbus_free (key); - +	      	    if (!check_message_handling_type (&child_iter, entry_type))  	      {  		_dbus_warn ("error in dict value\n"); @@ -4157,7 +4305,6 @@ check_message_handling (DBusMessage *message)    dbus_message_iter_init (message, &iter);    while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)      { -        if (!check_message_handling_type (&iter, type))  	goto failed; @@ -4645,6 +4792,7 @@ verify_test_message (DBusMessage *message)    double our_double;    dbus_bool_t our_bool;    dbus_int32_t *our_int_array; +  dbus_uint32_t our_uint32;    int our_int_array_len;    DBusMessageIter iter, dict;    DBusError error; @@ -4705,8 +4853,11 @@ verify_test_message (DBusMessage *message)        _dbus_assert_not_reached ("wrong dict entry type");      } -  if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF) -    _dbus_assert_not_reached ("wrong dict entry value"); +  if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF) +    { +      _dbus_verbose ("dict entry val: %x\n", our_uint32); +      _dbus_assert_not_reached ("wrong dict entry value"); +    }    if (dbus_message_iter_next (&dict))      _dbus_assert_not_reached ("Didn't reach end of dict"); @@ -4735,7 +4886,7 @@ _dbus_message_test (const char *test_data_dir)  {    DBusMessage *message;    DBusMessageLoader *loader; -  DBusMessageIter iter, child_iter; +  DBusMessageIter iter, child_iter, child_iter2, child_iter3;    int i;    const char *data;    DBusMessage *copy; @@ -4805,10 +4956,27 @@ _dbus_message_test (const char *test_data_dir)    dbus_message_iter_append_uint32 (&child_iter, 0x12345678);    dbus_message_iter_append_uint32 (&child_iter, 0x23456781); +  /* dict */    dbus_message_iter_append_dict (&iter, &child_iter);    dbus_message_iter_append_dict_key (&child_iter, "test");    dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF); + +  /* array of array of int32  (in dict) */ +  dbus_message_iter_append_dict_key (&child_iter, "array"); +  dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY); +  dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32); +  dbus_message_iter_append_int32 (&child_iter3, 0x12345678); +  dbus_message_iter_append_int32 (&child_iter3, 0x23456781); +  _dbus_warn ("next call expected to fail with wrong array type\n"); +  _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32)); +  dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32); +  dbus_message_iter_append_int32 (&child_iter3, 0x34567812); +  dbus_message_iter_append_int32 (&child_iter3, 0x45678123); +  dbus_message_iter_append_int32 (&child_iter3, 0x56781234); +      dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE); + +    message_iter_test (message); diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 6a940536..809dc3ed 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -48,6 +48,7 @@ struct DBusMessageIter    int dummy8;    int dummy9;    int dummy10; +  int dummy11;    int pad1;    int pad2;    void *pad3; diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index 5a7a80fa..0bbc3cda 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -10,6 +10,7 @@  	<firstname>Havoc</firstname>  	<surname>Pennington</surname>  	<affiliation> +	  <orgname>Red Hat, Inc</orgname>  	  <address>  	    <email>hp@pobox.com</email>  	  </address> @@ -25,6 +26,16 @@            </address>  	</affiliation>        </author> +      <author> +	<firstname>Alexander</firstname> +	<surname>Larsson</surname> +	<affiliation> +	  <orgname>Red Hat, Inc</orgname> +	  <address> +            <email>alexl@redhat.com</email> +          </address> +	</affiliation> +      </author>      </authorgroup>    </artheader> @@ -283,9 +294,6 @@          in a type-dependent format.        </para>        <para> -        [FIXME perhaps we should add type BYTE with the primary  -        advantage being that it occupies 1 byte vs. 7 for UINT32, -        or perhaps space savings aren't worth the complexity]          <informaltable>            <tgroup cols=3>              <thead> @@ -307,7 +315,7 @@                </row><row>  		<entry>BYTE</entry>  		<entry>2</entry> -		<entry>8-bit unsigned integer.</entry> +		<entry>8-bit unsigned integer</entry>                </row><row>  		<entry>BOOLEAN</entry>  		<entry>3</entry> @@ -365,10 +373,10 @@                  by the type code of the next argument.</entry>                </row><row>                  <entry>BYTE</entry> -                <entry>a byte.</entry> +                <entry>A byte.</entry>                </row><row>                  <entry>BOOLEAN</entry> -                <entry>a byte, with valid values 0 and 1.</entry> +                <entry>A byte, with valid values 0 and 1.</entry>                </row><row>                  <entry>INT32</entry>                  <entry>32-bit signed integer in the message's byte order, aligned to 4-byte boundary.</entry> @@ -393,11 +401,13 @@                  </entry>                </row><row>                  <entry>ARRAY</entry> -                <entry>a byte giving the element type of the array followed -                by an UINT32 (aligned to 4 bytes) giving the length of the -                array data in bytes. This is then followed by a number of -                entries with the same type, encoded like that type normally -                would be encoded alone. +                <entry>A sequence of bytes giving the element type of the array, terminated +                by a type different from ARRAY (just one byte for one-dimensional arrays, but +                larger for multi-dimensional arrays), followed by an UINT32 (aligned to 4 bytes) +                giving the length of the array data in bytes. This is followed by each array entry +                encoded the way it would normally be encoded, except arrays, which are encoded +                without the type information, since that is already declared above. Arrays containing +                NIL are not allowed.                  </entry>                </row><row>                  <entry>DICT</entry> @@ -1524,7 +1534,9 @@  	        <row>  		  <entry>DBUS_SERVICE_FLAGS_REPLACE_EXISTING</entry>  		  <entry>0x2</entry> -		  <entry>Only become the owner of the service if there is no current owner.</entry> +		  <entry>Try to replace the current owner if there is one. If this flag +                  is not set the application will only become the owner of the service if +                  there is no current owner.</entry>  	        </row>  	      </tbody>  	    </tgroup> diff --git a/test/data/invalid-messages/array-with-mixed-types.message b/test/data/invalid-messages/array-with-mixed-types.message index a7ff1e69..763a6c29 100644 --- a/test/data/invalid-messages/array-with-mixed-types.message +++ b/test/data/invalid-messages/array-with-mixed-types.message @@ -11,12 +11,12 @@ START_LENGTH Body  TYPE ARRAY  TYPE ARRAY +TYPE UINT32  LENGTH Array  START_LENGTH Array  ## array of uint32 -TYPE UINT32  LENGTH SubArray1  START_LENGTH SubArray1  UINT32 1 @@ -25,7 +25,6 @@ UINT32 3  END_LENGTH SubArray1  ## array of uint32 -TYPE UINT32  LENGTH SubArray2  START_LENGTH SubArray2  UINT32 4 @@ -33,13 +32,10 @@ UINT32 5  END_LENGTH SubArray2  ## array of boolean -TYPE BOOLEAN  LENGTH SubArray3  START_LENGTH SubArray3  BOOLEAN false  BOOLEAN true -BOOLEAN false -BOOLEAN true  END_LENGTH SubArray3  END_LENGTH Array diff --git a/test/data/invalid-messages/too-short-dict.message b/test/data/invalid-messages/too-short-dict.message index 14722023..ba200461 100644 --- a/test/data/invalid-messages/too-short-dict.message +++ b/test/data/invalid-messages/too-short-dict.message @@ -8,8 +8,11 @@ END_LENGTH Header  ALIGN 8  START_LENGTH Body  TYPE DICT +LENGTH Dict +START_LENGTH Dict  STRING 'uint32'  TYPE UINT32  UINT32 0x8765432  STRING 'uint32' +END_LENGTH Dict  END_LENGTH Body diff --git a/test/data/valid-messages/array-of-array-of-uint32.message b/test/data/valid-messages/array-of-array-of-uint32.message index 6baf4c36..82b8273d 100644 --- a/test/data/valid-messages/array-of-array-of-uint32.message +++ b/test/data/valid-messages/array-of-array-of-uint32.message @@ -10,12 +10,12 @@ START_LENGTH Body  TYPE ARRAY  TYPE ARRAY +TYPE UINT32  LENGTH Array  START_LENGTH Array  ## array of uint32 -TYPE UINT32  LENGTH SubArray1  START_LENGTH SubArray1  UINT32 1 @@ -24,7 +24,6 @@ UINT32 3  END_LENGTH SubArray1  ## array of uint32 -TYPE UINT32  LENGTH SubArray2  START_LENGTH SubArray2  UINT32 4 diff --git a/test/data/valid-messages/recursive-types.message b/test/data/valid-messages/recursive-types.message index b7608041..2ac6ad13 100644 --- a/test/data/valid-messages/recursive-types.message +++ b/test/data/valid-messages/recursive-types.message @@ -10,56 +10,91 @@ STRING 'org.freedesktop.Foo'  END_LENGTH Header  START_LENGTH Body +# Everything is inside a dict +TYPE DICT +LENGTH Dict1 +START_LENGTH Dict1 + +# first dict entry is an array of array of uint32 +STRING 'mega-uint-array' +TYPE ARRAY  TYPE ARRAY  TYPE ARRAY +TYPE UINT32  LENGTH Array1  START_LENGTH Array1 - -TYPE UINT32 +LENGTH Array1_1 +START_LENGTH Array1_1  UINT32_ARRAY { 1, 2, 3, 4, 5} +UINT32_ARRAY { 2, 3, 4, 5, 1} +UINT32_ARRAY { 3, 4, 5, 1, 2} +END_LENGTH Array1_1 +LENGTH Array1_2 +START_LENGTH Array1_2 +UINT32_ARRAY { 4, 5, 6, 7, 8} +UINT32_ARRAY { 5, 6, 7, 8, 4} +END_LENGTH Array1_2 + +END_LENGTH Array1 +# second dict entry is an array of strings +STRING 'string-array' +TYPE ARRAY  TYPE STRING  STRING_ARRAY { 'a', 'string', 'array'} - +# third dict entry is another dict +STRING 'nested-dict'  TYPE DICT -LENGTH Array2 -START_LENGTH Array2 - -LENGTH Dict1 -START_LENGTH Dict1 -STRING 'uint32' -TYPE UINT32 -UINT32 1234     -STRING uint32' -TYPE INT32 -INT32 1234     -END_LENGTH Dict1 -  LENGTH Dict2  START_LENGTH Dict2 -STRING 'dict' +STRING 'string' +TYPE STRING +STRING 'a deeply nested string'      + +STRING 'super-nested-dict'  TYPE DICT  LENGTH Dict3  START_LENGTH Dict3 +  STRING 'double-array'  TYPE ARRAY  TYPE DOUBLE  DOUBLE_ARRAY {1.0, 2.0, 3.0} + +STRING 'dict-array' +TYPE ARRAY +TYPE DICT +LENGTH Array2 +START_LENGTH Array2 + +LENGTH Dict4 +START_LENGTH Dict4 +STRING 'key4' +TYPE BYTE +BYTE '4' +END_LENGTH Dict4 + +LENGTH Dict5 +START_LENGTH Dict5 +STRING 'key5' +TYPE BYTE +BYTE '5' +END_LENGTH Dict5 + +END_LENGTH Array2 +  STRING 'boolean'  TYPE BOOLEAN  BOOLEAN false +  END_LENGTH Dict3  END_LENGTH Dict2 -END_LENGTH Array2 - - -END_LENGTH Array1 - +END_LENGTH Dict1  END_LENGTH Body | 
