diff options
-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 |