1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c Marshalling routines
4 * Copyright (C) 2002 CodeFactory AB
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-marshal.h"
25 #include "dbus-internals.h"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
33 swap_bytes (unsigned char *data,
36 unsigned char *p1 = data;
37 unsigned char *p2 = data + len - 1;
41 unsigned char tmp = *p1;
51 * @defgroup DBusMarshal marshaling and unmarshaling
52 * @ingroup DBusInternals
53 * @brief functions to marshal/unmarshal data from the wire
55 * Types and functions related to converting primitive data types from
56 * wire format to native machine format, and vice versa.
62 * Unpacks a 32 bit unsigned integer from a data pointer
64 * @param byte_order The byte order to use
65 * @param data the data pointer
66 * @returns the integer
69 _dbus_unpack_uint32 (int byte_order,
70 const unsigned char *data)
72 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
74 if (byte_order == DBUS_LITTLE_ENDIAN)
75 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
77 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
81 * Unpacks a 32 bit signed integer from a data pointer
83 * @param byte_order The byte order to use
84 * @param data the data pointer
85 * @returns the integer
88 _dbus_unpack_int32 (int byte_order,
89 const unsigned char *data)
91 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
93 if (byte_order == DBUS_LITTLE_ENDIAN)
94 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
96 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
100 * Packs a 32 bit unsigned integer into a data pointer.
102 * @param value the value
103 * @param byte_order the byte order to use
104 * @param data the data pointer
107 _dbus_pack_uint32 (dbus_uint32_t value,
111 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
113 if ((byte_order) == DBUS_LITTLE_ENDIAN)
114 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
116 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
120 * Packs a 32 bit signed integer into a data pointer.
122 * @param value the value
123 * @param byte_order the byte order to use
124 * @param data the data pointer
127 _dbus_pack_int32 (dbus_int32_t value,
131 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
133 if ((byte_order) == DBUS_LITTLE_ENDIAN)
134 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);
136 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
140 * Sets the 4 bytes at the given offset to a marshaled signed integer,
141 * replacing anything found there previously.
143 * @param str the string to write the marshalled int to
144 * @param offset the byte offset where int should be written
145 * @param byte_order the byte order to use
146 * @param value the value
150 _dbus_marshal_set_int32 (DBusString *str,
157 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
158 byte_order == DBUS_BIG_ENDIAN);
160 data = _dbus_string_get_data_len (str, offset, 4);
162 _dbus_pack_int32 (value, byte_order, data);
166 * Sets the 4 bytes at the given offset to a marshaled unsigned
167 * integer, replacing anything found there previously.
169 * @param str the string to write the marshalled int to
170 * @param offset the byte offset where int should be written
171 * @param byte_order the byte order to use
172 * @param value the value
176 _dbus_marshal_set_uint32 (DBusString *str,
183 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
184 byte_order == DBUS_BIG_ENDIAN);
186 data = _dbus_string_get_data_len (str, offset, 4);
188 _dbus_pack_uint32 (value, byte_order, data);
192 * Sets the existing marshaled string at the given offset with
193 * a new marshaled string. The given offset must point to
194 * an existing string or the wrong length will be deleted
195 * and replaced with the new string.
197 * @param str the string to write the marshalled string to
198 * @param offset the byte offset where string should be written
199 * @param byte_order the byte order to use
200 * @param value the value
201 * @param len the length to use
202 * @returns #TRUE on success
206 _dbus_marshal_set_string (DBusString *str,
209 const DBusString *value,
214 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
215 byte_order == DBUS_BIG_ENDIAN);
217 old_len = _dbus_demarshal_uint32 (str, byte_order,
220 if (!_dbus_string_replace_len (value, 0, len,
221 str, offset + 4, old_len))
224 _dbus_marshal_set_uint32 (str, byte_order,
231 * Marshals a double value.
233 * @param str the string to append the marshalled value to
234 * @param byte_order the byte order to use
235 * @param value the value
236 * @returns #TRUE on success
239 _dbus_marshal_double (DBusString *str,
243 _dbus_assert (sizeof (double) == 8);
245 if (!_dbus_string_align_length (str, sizeof (double)))
248 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
249 swap_bytes ((unsigned char *)&value, sizeof (double));
251 return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
255 * Marshals a 32 bit signed integer value.
257 * @param str the string to append the marshalled value to
258 * @param byte_order the byte order to use
259 * @param value the value
260 * @returns #TRUE on success
263 _dbus_marshal_int32 (DBusString *str,
267 if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
270 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
271 value = DBUS_INT32_SWAP_LE_BE (value);
273 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
277 * Marshals a 32 bit unsigned integer value.
279 * @param str the string to append the marshalled value to
280 * @param byte_order the byte order to use
281 * @param value the value
282 * @returns #TRUE on success
285 _dbus_marshal_uint32 (DBusString *str,
289 if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
292 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
293 value = DBUS_UINT32_SWAP_LE_BE (value);
295 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
299 * Marshals a UTF-8 string
301 * @todo: If the string append fails we need to restore
302 * the old length. (also for other marshallers)
304 * @param str the string to append the marshalled value to
305 * @param byte_order the byte order to use
306 * @param value the string
307 * @returns #TRUE on success
310 _dbus_marshal_string (DBusString *str,
314 int len, old_string_len;
316 old_string_len = _dbus_string_get_length (str);
318 len = strlen (value);
320 if (!_dbus_marshal_uint32 (str, byte_order, len))
322 /* Restore the previous length */
323 _dbus_string_set_length (str, old_string_len);
328 return _dbus_string_append_len (str, value, len + 1);
332 * Marshals a byte array
334 * @param str the string to append the marshalled value to
335 * @param byte_order the byte order to use
336 * @param value the array
337 * @param len number of elements in the array
338 * @returns #TRUE on success
341 _dbus_marshal_byte_array (DBusString *str,
343 const unsigned char *value,
348 old_string_len = _dbus_string_get_length (str);
350 if (!_dbus_marshal_uint32 (str, byte_order, len))
352 /* Restore the previous length */
353 _dbus_string_set_length (str, old_string_len);
361 return _dbus_string_append_len (str, value, len);
365 * Marshals a 32 bit signed integer array
367 * @param str the string to append the marshalled value to
368 * @param byte_order the byte order to use
369 * @param value the array
370 * @param len the length of the array
371 * @returns #TRUE on success
374 _dbus_marshal_int32_array (DBusString *str,
376 const dbus_int32_t *value,
379 int i, old_string_len;
381 old_string_len = _dbus_string_get_length (str);
383 if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_int32_t)))
386 for (i = 0; i < len; i++)
387 if (!_dbus_marshal_int32 (str, byte_order, value[i]))
393 /* Restore previous length */
394 _dbus_string_set_length (str, old_string_len);
400 * Marshals a 32 bit unsigned integer array
402 * @param str the string to append the marshalled value to
403 * @param byte_order the byte order to use
404 * @param value the array
405 * @param len the length of the array
406 * @returns #TRUE on success
409 _dbus_marshal_uint32_array (DBusString *str,
411 const dbus_uint32_t *value,
414 int i, old_string_len;
416 old_string_len = _dbus_string_get_length (str);
418 if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_uint32_t)))
421 for (i = 0; i < len; i++)
422 if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
428 /* Restore previous length */
429 _dbus_string_set_length (str, old_string_len);
435 * Marshals a double array
437 * @param str the string to append the marshalled value to
438 * @param byte_order the byte order to use
439 * @param value the array
440 * @param len the length of the array
441 * @returns #TRUE on success
444 _dbus_marshal_double_array (DBusString *str,
449 int i, old_string_len, array_start;
451 old_string_len = _dbus_string_get_length (str);
453 /* Set the length to 0 temporarily */
454 if (!_dbus_marshal_uint32 (str, byte_order, 0))
457 array_start = _dbus_string_get_length (str);
459 for (i = 0; i < len; i++)
460 if (!_dbus_marshal_double (str, byte_order, value[i]))
463 /* Write the length now that we know it */
464 _dbus_marshal_set_uint32 (str, byte_order,
465 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
466 _dbus_string_get_length (str) - array_start);
471 /* Restore previous length */
472 _dbus_string_set_length (str, old_string_len);
478 * Marshals a string array
480 * @param str the string to append the marshalled value to
481 * @param byte_order the byte order to use
482 * @param value the array
483 * @param len the length of the array
484 * @returns #TRUE on success
487 _dbus_marshal_string_array (DBusString *str,
492 int i, old_string_len, array_start;
494 old_string_len = _dbus_string_get_length (str);
496 /* Set the length to 0 temporarily */
497 if (!_dbus_marshal_uint32 (str, byte_order, 0))
500 array_start = _dbus_string_get_length (str);
502 for (i = 0; i < len; i++)
503 if (!_dbus_marshal_string (str, byte_order, value[i]))
506 /* Write the length now that we know it */
507 _dbus_marshal_set_uint32 (str, byte_order,
508 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
509 _dbus_string_get_length (str) - array_start);
514 /* Restore previous length */
515 _dbus_string_set_length (str, old_string_len);
522 * Demarshals a double.
524 * @param str the string containing the data
525 * @param byte_order the byte order
526 * @param pos the position in the string
527 * @param new_pos the new position of the string
528 * @returns the demarshaled double.
531 _dbus_demarshal_double (const DBusString *str,
539 pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
541 buffer = _dbus_string_get_const_data_len (str, pos, sizeof (double));
543 retval = *(double *)buffer;
545 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
546 swap_bytes ((unsigned char *)&retval, sizeof (double));
549 *new_pos = pos + sizeof (double);
555 * Demarshals a 32 bit signed integer.
557 * @param str the string containing the data
558 * @param byte_order the byte order
559 * @param pos the position in the string
560 * @param new_pos the new position of the string
561 * @returns the demarshaled integer.
564 _dbus_demarshal_int32 (const DBusString *str,
569 const DBusRealString *real = (const DBusRealString*) str;
571 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
574 *new_pos = pos + sizeof (dbus_int32_t);
576 if (byte_order == DBUS_LITTLE_ENDIAN)
577 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
579 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
583 * Demarshals a 32 bit unsigned integer.
585 * @param str the string containing the data
586 * @param byte_order the byte order
587 * @param pos the position in the string
588 * @param new_pos the new position of the string
589 * @returns the demarshaled integer.
592 _dbus_demarshal_uint32 (const DBusString *str,
597 const DBusRealString *real = (const DBusRealString*) str;
599 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
602 *new_pos = pos + sizeof (dbus_uint32_t);
604 if (byte_order == DBUS_LITTLE_ENDIAN)
605 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
607 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
611 * Demarshals an UTF-8 string.
613 * @todo Should we check the string to make sure
614 * that it's valid UTF-8, and maybe "fix" the string
617 * @todo Should probably demarshal to a DBusString,
618 * having memcpy() in here is Evil(tm).
620 * @param str the string containing the data
621 * @param byte_order the byte order
622 * @param pos the position in the string
623 * @param new_pos the new position of the string
624 * @returns the demarshaled string.
627 _dbus_demarshal_string (const DBusString *str,
636 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
638 retval = dbus_malloc (len + 1);
643 data = _dbus_string_get_const_data_len (str, pos, len + 1);
648 memcpy (retval, data, len + 1);
651 *new_pos = pos + len + 1;
657 * Demarshals a byte array.
659 * @todo Should probably demarshal to a DBusString,
660 * having memcpy() in here is Evil(tm).
662 * @param str the string containing the data
663 * @param byte_order the byte order
664 * @param pos the position in the string
665 * @param new_pos the new position of the string
666 * @param array the array
667 * @param array_len length of the demarshaled data
669 * @returns #TRUE on success
672 _dbus_demarshal_byte_array (const DBusString *str,
676 unsigned char **array,
680 unsigned char *retval;
683 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
696 retval = dbus_malloc (len);
701 data = _dbus_string_get_const_data_len (str, pos, len);
709 memcpy (retval, data, len);
712 *new_pos = pos + len;
721 * Demarshals a 32 bit signed integer array.
723 * @param str the string containing the data
724 * @param byte_order the byte order
725 * @param pos the position in the string
726 * @param new_pos the new position of the string
727 * @param array the array
728 * @param array_len length of the demarshaled data
729 * @returns #TRUE on success
732 _dbus_demarshal_int32_array (const DBusString *str,
736 dbus_int32_t **array,
740 dbus_int32_t *retval;
742 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_int32_t);
755 retval = dbus_new (dbus_int32_t, len);
760 for (i = 0; i < len; i++)
761 retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
773 * Demarshals a 32 bit unsigned integer array.
775 * @param str the string containing the data
776 * @param byte_order the byte order
777 * @param pos the position in the string
778 * @param new_pos the new position of the string
779 * @param array the array
780 * @param array_len length of the demarshaled data
781 * @returns #TRUE on success
784 _dbus_demarshal_uint32_array (const DBusString *str,
788 dbus_uint32_t **array,
792 dbus_uint32_t *retval;
794 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_uint32_t);
807 retval = dbus_new (dbus_uint32_t, len);
812 for (i = 0; i < len; i++)
813 retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
825 * Demarshals a double array.
827 * @param str the string containing the data
828 * @param byte_order the byte order
829 * @param pos the position in the string
830 * @param new_pos the new position of the string
831 * @param array the array
832 * @param array_len length of the demarshaled data
833 * @returns #TRUE on success
836 _dbus_demarshal_double_array (const DBusString *str,
846 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (double);
859 retval = dbus_new (double, len);
864 for (i = 0; i < len; i++)
865 retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
877 * Demarshals a string array.
879 * @param str the string containing the data
880 * @param byte_order the byte order
881 * @param pos the position in the string
882 * @param new_pos the new position of the string
883 * @param array the array
884 * @param array_len length of the demarshaled data
885 * @returns #TRUE on success
888 _dbus_demarshal_string_array (const DBusString *str,
898 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
911 retval = dbus_new (char *, len + 1);
918 for (i = 0; i < len; i++)
920 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
935 for (j = 0; j < i; j++)
936 dbus_free (retval[i]);
943 * Returns the position right after the end of an argument. PERFORMS
944 * NO VALIDATION WHATSOEVER. The message must have been previously
947 * @param str a string
948 * @param byte_order the byte order to use
949 * @param type the type of the argument
950 * @param pos the pos where the arg starts
951 * @param end_pos pointer where the position right
952 * after the end position will follow
953 * @returns TRUE if more data exists after the arg
956 _dbus_marshal_get_arg_end_pos (const DBusString *str,
962 if (pos >= _dbus_string_get_length (str))
967 case DBUS_TYPE_INVALID:
979 case DBUS_TYPE_BOOLEAN:
983 case DBUS_TYPE_INT32:
984 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
988 case DBUS_TYPE_UINT32:
989 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
993 case DBUS_TYPE_DOUBLE:
994 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
998 case DBUS_TYPE_STRING:
1002 /* Demarshal the length */
1003 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1005 *end_pos = pos + len + 1;
1009 case DBUS_TYPE_NAMED:
1013 /* Demarshal the string length */
1014 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1016 *end_pos = pos + len + 1;
1018 /* Demarshal the data length */
1019 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1021 *end_pos = pos + len;
1025 case DBUS_TYPE_ARRAY:
1029 /* Demarshal the length (element type is at pos + 0 */
1030 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1032 *end_pos = pos + len;
1036 case DBUS_TYPE_DICT:
1040 /* Demarshal the length */
1041 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1043 *end_pos = pos + len;
1048 _dbus_warn ("Unknown message arg type %d\n", type);
1049 _dbus_assert_not_reached ("Unknown message argument type\n");
1053 if (*end_pos > _dbus_string_get_length (str))
1060 * Demarshals and validates a length; returns < 0 if the validation
1061 * fails. The length is required to be small enough that
1062 * len*sizeof(double) will not overflow, and small enough to fit in a
1063 * signed integer. DOES NOT check whether the length points
1064 * beyond the end of the string, because it doesn't know the
1065 * size of array elements.
1067 * @param str the string
1068 * @param byte_order the byte order
1069 * @param pos the unaligned string position (snap to next aligned)
1070 * @param new_pos return location for new position.
1073 demarshal_and_validate_len (const DBusString *str,
1078 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1081 _dbus_assert (new_pos != NULL);
1083 if ((align_4 + 4) > _dbus_string_get_length (str))
1085 _dbus_verbose ("not enough room in message for array length\n");
1089 if (!_dbus_string_validate_nul (str, pos,
1092 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1096 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1098 /* note that the len is the number of bytes, so we need it to be
1099 * at least SIZE_T_MAX, but make it smaller just to keep things
1100 * sane. We end up using ints for most sizes to avoid unsigned mess
1101 * so limit to maximum 32-bit signed int divided by at least 8, more
1102 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1104 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1105 if (len > MAX_ARRAY_LENGTH)
1107 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1108 len, MAX_ARRAY_LENGTH);
1116 validate_string (const DBusString *str,
1118 int len_without_nul,
1121 *end_pos = pos + len_without_nul + 1;
1123 if (*end_pos > _dbus_string_get_length (str))
1125 _dbus_verbose ("string length outside length of the message\n");
1129 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1131 _dbus_verbose ("string arg not nul-terminated\n");
1135 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1137 _dbus_verbose ("string is not valid UTF-8\n");
1145 * Validates and returns a typecode at a specific position
1148 * @param str a string
1149 * @param type the type of the argument
1150 * @param pos the pos where the typecode starts
1151 * @param end_pos pointer where the position right
1152 * after the end position will follow
1153 * @returns #TRUE if the type is valid.
1156 _dbus_marshal_validate_type (const DBusString *str,
1163 if (pos >= _dbus_string_get_length (str))
1166 data = _dbus_string_get_const_data_len (str, pos, 1);
1168 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1180 * Validates an argument of a specific type, checking that it
1181 * is well-formed, for example no ludicrous length fields, strings
1182 * are nul-terminated, etc.
1183 * Returns the end position of the argument in end_pos, and
1184 * returns #TRUE if a valid arg begins at "pos"
1186 * @todo security: need to audit this function.
1188 * @todo For array types that can't be invalid, we should not
1189 * walk the whole array validating it. e.g. just skip all the
1190 * int values in an int array.
1192 * @param str a string
1193 * @param byte_order the byte order to use
1194 * @param depth current recursion depth, to prevent excessive recursion
1195 * @param type the type of the argument
1196 * @param pos the pos where the arg starts
1197 * @param end_pos pointer where the position right
1198 * after the end position will follow
1199 * @returns #TRUE if the arg is valid.
1202 _dbus_marshal_validate_arg (const DBusString *str,
1209 if (pos > _dbus_string_get_length (str))
1211 _dbus_verbose ("Validation went off the end of the message\n");
1215 #define MAX_VALIDATION_DEPTH 32
1217 if (depth > MAX_VALIDATION_DEPTH)
1219 _dbus_verbose ("Maximum recursion depth reached validating message\n");
1225 case DBUS_TYPE_INVALID:
1233 case DBUS_TYPE_BYTE:
1234 if (1 > _dbus_string_get_length (str) - pos)
1236 _dbus_verbose ("no room for byte value\n");
1243 case DBUS_TYPE_BOOLEAN:
1247 if (1 > _dbus_string_get_length (str) - pos)
1249 _dbus_verbose ("no room for boolean value\n");
1253 c = _dbus_string_get_byte (str, pos);
1255 if (c != 0 && c != 1)
1257 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1264 case DBUS_TYPE_INT32:
1265 case DBUS_TYPE_UINT32:
1267 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1269 if (!_dbus_string_validate_nul (str, pos,
1272 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1276 *end_pos = align_4 + 4;
1280 case DBUS_TYPE_DOUBLE:
1282 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1284 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1286 if (!_dbus_string_validate_nul (str, pos,
1289 _dbus_verbose ("double alignment padding not initialized to nul\n");
1293 *end_pos = align_8 + 8;
1297 case DBUS_TYPE_STRING:
1301 /* Demarshal the length, which does NOT include
1304 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1308 if (!validate_string (str, pos, len, end_pos))
1313 case DBUS_TYPE_NAMED:
1317 /* Demarshal the string length, which does NOT include
1320 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1324 if (!validate_string (str, pos, len, &pos))
1328 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1332 *end_pos = pos + len;
1336 case DBUS_TYPE_ARRAY:
1342 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1344 _dbus_verbose ("invalid array type\n");
1348 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1352 if (len > _dbus_string_get_length (str) - pos)
1354 _dbus_verbose ("array length outside length of the message\n");
1362 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1363 array_type, pos, &pos))
1369 _dbus_verbose ("array contents exceeds array length\n");
1377 case DBUS_TYPE_DICT:
1383 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1387 if (len > _dbus_string_get_length (str) - pos)
1389 _dbus_verbose ("dict length outside length of the message\n");
1398 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1399 DBUS_TYPE_STRING, pos, &pos))
1402 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
1404 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
1408 /* Validate element */
1409 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1410 dict_type, pos, &pos))
1416 _dbus_verbose ("dict contents exceeds array length\n");
1424 _dbus_verbose ("Unknown message arg type %d\n", type);
1428 if (*end_pos > _dbus_string_get_length (str))
1436 * If in verbose mode, print a block of binary data.
1438 * @todo right now it prints even if not in verbose mode
1440 * @param data the data
1441 * @param len the length of the data
1444 _dbus_verbose_bytes (const unsigned char *data,
1448 const unsigned char *aligned;
1450 _dbus_assert (len >= 0);
1452 /* Print blanks on first row if appropriate */
1453 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1456 _dbus_assert (aligned <= data);
1458 if (aligned != data)
1460 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1461 while (aligned != data)
1463 _dbus_verbose (" ");
1468 /* now print the bytes */
1472 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1474 _dbus_verbose ("%4d\t%p: ",
1478 if (data[i] >= 32 &&
1480 _dbus_verbose (" '%c' ", data[i]);
1482 _dbus_verbose ("0x%s%x ",
1483 data[i] <= 0xf ? "0" : "", data[i]);
1487 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1490 _dbus_verbose ("BE: %d LE: %d",
1491 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1492 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1495 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1497 _dbus_verbose (" dbl: %g",
1498 *(double*)&data[i-8]);
1501 _dbus_verbose ("\n");
1505 _dbus_verbose ("\n");
1509 * Dump the given part of the string to verbose log.
1511 * @param str the string
1512 * @param start the start of range to dump
1513 * @param len length of range
1516 _dbus_verbose_bytes_of_string (const DBusString *str,
1523 real_len = _dbus_string_get_length (str);
1525 _dbus_assert (start >= 0);
1527 if (start > real_len)
1529 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1530 start, len, real_len);
1534 if ((start + len) > real_len)
1536 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1537 start, len, real_len);
1538 len = real_len - start;
1541 d = _dbus_string_get_const_data_len (str, start, len);
1543 _dbus_verbose_bytes (d, len);
1548 #ifdef DBUS_BUILD_TESTS
1549 #include "dbus-test.h"
1553 _dbus_marshal_test (void)
1557 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1560 if (!_dbus_string_init (&str))
1561 _dbus_assert_not_reached ("failed to init string");
1563 /* Marshal doubles */
1564 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1565 _dbus_assert_not_reached ("could not marshal double value");
1566 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1567 _dbus_assert_not_reached ("demarshal failed");
1569 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1570 _dbus_assert_not_reached ("could not marshal double value");
1571 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1572 _dbus_assert_not_reached ("demarshal failed");
1574 /* Marshal signed integers */
1575 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1576 _dbus_assert_not_reached ("could not marshal signed integer value");
1577 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1578 _dbus_assert_not_reached ("demarshal failed");
1580 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1581 _dbus_assert_not_reached ("could not marshal signed integer value");
1582 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1583 _dbus_assert_not_reached ("demarshal failed");
1585 /* Marshal unsigned integers */
1586 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1587 _dbus_assert_not_reached ("could not marshal signed integer value");
1588 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1589 _dbus_assert_not_reached ("demarshal failed");
1591 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1592 _dbus_assert_not_reached ("could not marshal signed integer value");
1593 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1594 _dbus_assert_not_reached ("demarshal failed");
1596 /* Marshal strings */
1597 tmp1 = "This is the dbus test string";
1598 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1599 _dbus_assert_not_reached ("could not marshal string");
1600 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1601 if (!strcmp (tmp1, tmp2) == 0)
1602 _dbus_assert_not_reached ("demarshal failed");
1605 tmp1 = "This is the dbus test string";
1606 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1607 _dbus_assert_not_reached ("could not marshal string");
1608 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1609 if (!strcmp (tmp1, tmp2) == 0)
1610 _dbus_assert_not_reached ("demarshal failed");
1613 /* Marshal signed integer arrays */
1614 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1615 _dbus_assert_not_reached ("could not marshal integer array");
1616 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
1617 _dbus_assert_not_reached ("could not demarshal integer array");
1620 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1623 _dbus_string_free (&str);
1629 #endif /* DBUS_BUILD_TESTS */