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.
This commit is contained in:
Alexander Larsson 2003-04-10 11:04:24 +00:00
parent 51781f5410
commit e84c3a03b3
10 changed files with 456 additions and 193 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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
@ -1586,6 +1589,21 @@ dbus_message_iter_check (DBusMessageRealIter *iter)
_dbus_warn ("dbus iterator check failed: invalid position\n");
}
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)
{
@ -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);

View file

@ -48,6 +48,7 @@ struct DBusMessageIter
int dummy8;
int dummy9;
int dummy10;
int dummy11;
int pad1;
int pad2;
void *pad3;

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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