1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c Marshalling routines
4 * Copyright (C) 2002 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the Academic Free License version 1.2
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "dbus-marshal.h"
26 #include "dbus-internals.h"
27 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
28 #include "dbus-string-private.h"
34 swap_bytes (unsigned char *data,
37 unsigned char *p1 = data;
38 unsigned char *p2 = data + len - 1;
42 unsigned char tmp = *p1;
52 * @defgroup DBusMarshal marshaling and unmarshaling
53 * @ingroup DBusInternals
54 * @brief functions to marshal/unmarshal data from the wire
56 * Types and functions related to converting primitive data types from
57 * wire format to native machine format, and vice versa.
63 * Unpacks a 32 bit unsigned integer from a data pointer
65 * @param byte_order The byte order to use
66 * @param data the data pointer
67 * @returns the integer
70 _dbus_unpack_uint32 (int byte_order,
71 const unsigned char *data)
73 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
75 if (byte_order == DBUS_LITTLE_ENDIAN)
76 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
78 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
82 * Unpacks a 32 bit signed integer from a data pointer
84 * @param byte_order The byte order to use
85 * @param data the data pointer
86 * @returns the integer
89 _dbus_unpack_int32 (int byte_order,
90 const unsigned char *data)
92 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
94 if (byte_order == DBUS_LITTLE_ENDIAN)
95 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
97 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
101 * Packs a 32 bit unsigned integer into a data pointer.
103 * @param value the value
104 * @param byte_order the byte order to use
105 * @param data the data pointer
108 _dbus_pack_uint32 (dbus_uint32_t value,
112 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
114 if ((byte_order) == DBUS_LITTLE_ENDIAN)
115 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
117 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
121 * Packs a 32 bit signed integer into a data pointer.
123 * @param value the value
124 * @param byte_order the byte order to use
125 * @param data the data pointer
128 _dbus_pack_int32 (dbus_int32_t value,
132 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
134 if ((byte_order) == DBUS_LITTLE_ENDIAN)
135 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);
137 *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
141 * Sets the 4 bytes at the given offset to a marshaled signed integer,
142 * replacing anything found there previously.
144 * @param str the string to write the marshalled int to
145 * @param offset the byte offset where int should be written
146 * @param byte_order the byte order to use
147 * @param value the value
151 _dbus_marshal_set_int32 (DBusString *str,
158 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
159 byte_order == DBUS_BIG_ENDIAN);
161 data = _dbus_string_get_data_len (str, offset, 4);
163 _dbus_pack_int32 (value, byte_order, data);
167 * Sets the 4 bytes at the given offset to a marshaled unsigned
168 * integer, replacing anything found there previously.
170 * @param str the string to write the marshalled int to
171 * @param offset the byte offset where int should be written
172 * @param byte_order the byte order to use
173 * @param value the value
177 _dbus_marshal_set_uint32 (DBusString *str,
184 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
185 byte_order == DBUS_BIG_ENDIAN);
187 data = _dbus_string_get_data_len (str, offset, 4);
189 _dbus_pack_uint32 (value, byte_order, data);
193 * Sets the existing marshaled string at the given offset with
194 * a new marshaled string. The given offset must point to
195 * an existing string or the wrong length will be deleted
196 * and replaced with the new string.
198 * @param str the string to write the marshalled string to
199 * @param offset the byte offset where string should be written
200 * @param byte_order the byte order to use
201 * @param value the value
202 * @param len the length to use
203 * @returns #TRUE on success
207 _dbus_marshal_set_string (DBusString *str,
210 const DBusString *value,
215 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
216 byte_order == DBUS_BIG_ENDIAN);
218 old_len = _dbus_demarshal_uint32 (str, byte_order,
221 if (!_dbus_string_replace_len (value, 0, len,
222 str, offset + 4, old_len))
225 _dbus_marshal_set_uint32 (str, byte_order,
232 * Marshals a double value.
234 * @param str the string to append the marshalled value to
235 * @param byte_order the byte order to use
236 * @param value the value
237 * @returns #TRUE on success
240 _dbus_marshal_double (DBusString *str,
244 _dbus_assert (sizeof (double) == 8);
246 if (!_dbus_string_align_length (str, sizeof (double)))
249 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
250 swap_bytes ((unsigned char *)&value, sizeof (double));
252 return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
256 * Marshals a 32 bit signed integer value.
258 * @param str the string to append the marshalled value to
259 * @param byte_order the byte order to use
260 * @param value the value
261 * @returns #TRUE on success
264 _dbus_marshal_int32 (DBusString *str,
268 if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
271 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
272 value = DBUS_INT32_SWAP_LE_BE (value);
274 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
278 * Marshals a 32 bit unsigned integer value.
280 * @param str the string to append the marshalled value to
281 * @param byte_order the byte order to use
282 * @param value the value
283 * @returns #TRUE on success
286 _dbus_marshal_uint32 (DBusString *str,
290 if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
293 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
294 value = DBUS_UINT32_SWAP_LE_BE (value);
296 return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
300 * Marshals a UTF-8 string
302 * @todo: If the string append fails we need to restore
303 * the old length. (also for other marshallers)
305 * @param str the string to append the marshalled value to
306 * @param byte_order the byte order to use
307 * @param value the string
308 * @returns #TRUE on success
311 _dbus_marshal_string (DBusString *str,
315 int len, old_string_len;
317 old_string_len = _dbus_string_get_length (str);
319 len = strlen (value);
321 if (!_dbus_marshal_uint32 (str, byte_order, len))
323 /* Restore the previous length */
324 _dbus_string_set_length (str, old_string_len);
329 return _dbus_string_append_len (str, value, len + 1);
333 * Marshals a byte array
335 * @param str the string to append the marshalled value to
336 * @param byte_order the byte order to use
337 * @param value the array
338 * @param len number of elements in the array
339 * @returns #TRUE on success
342 _dbus_marshal_byte_array (DBusString *str,
344 const unsigned char *value,
349 old_string_len = _dbus_string_get_length (str);
351 if (!_dbus_marshal_uint32 (str, byte_order, len))
353 /* Restore the previous length */
354 _dbus_string_set_length (str, old_string_len);
362 return _dbus_string_append_len (str, value, len);
366 * Marshals a 32 bit signed integer array
368 * @param str the string to append the marshalled value to
369 * @param byte_order the byte order to use
370 * @param value the array
371 * @param len the length of the array
372 * @returns #TRUE on success
375 _dbus_marshal_int32_array (DBusString *str,
377 const dbus_int32_t *value,
380 int i, old_string_len;
382 old_string_len = _dbus_string_get_length (str);
384 if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_int32_t)))
387 for (i = 0; i < len; i++)
388 if (!_dbus_marshal_int32 (str, byte_order, value[i]))
394 /* Restore previous length */
395 _dbus_string_set_length (str, old_string_len);
401 * Marshals a 32 bit unsigned integer array
403 * @param str the string to append the marshalled value to
404 * @param byte_order the byte order to use
405 * @param value the array
406 * @param len the length of the array
407 * @returns #TRUE on success
410 _dbus_marshal_uint32_array (DBusString *str,
412 const dbus_uint32_t *value,
415 int i, old_string_len;
417 old_string_len = _dbus_string_get_length (str);
419 if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_uint32_t)))
422 for (i = 0; i < len; i++)
423 if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
429 /* Restore previous length */
430 _dbus_string_set_length (str, old_string_len);
436 * Marshals a double array
438 * @param str the string to append the marshalled value to
439 * @param byte_order the byte order to use
440 * @param value the array
441 * @param len the length of the array
442 * @returns #TRUE on success
445 _dbus_marshal_double_array (DBusString *str,
450 int i, old_string_len, array_start;
452 old_string_len = _dbus_string_get_length (str);
454 /* Set the length to 0 temporarily */
455 if (!_dbus_marshal_uint32 (str, byte_order, 0))
458 array_start = _dbus_string_get_length (str);
460 for (i = 0; i < len; i++)
461 if (!_dbus_marshal_double (str, byte_order, value[i]))
464 /* Write the length now that we know it */
465 _dbus_marshal_set_uint32 (str, byte_order,
466 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
467 _dbus_string_get_length (str) - array_start);
472 /* Restore previous length */
473 _dbus_string_set_length (str, old_string_len);
479 * Marshals a string array
481 * @param str the string to append the marshalled value to
482 * @param byte_order the byte order to use
483 * @param value the array
484 * @param len the length of the array
485 * @returns #TRUE on success
488 _dbus_marshal_string_array (DBusString *str,
493 int i, old_string_len, array_start;
495 old_string_len = _dbus_string_get_length (str);
497 /* Set the length to 0 temporarily */
498 if (!_dbus_marshal_uint32 (str, byte_order, 0))
501 array_start = _dbus_string_get_length (str);
503 for (i = 0; i < len; i++)
504 if (!_dbus_marshal_string (str, byte_order, value[i]))
507 /* Write the length now that we know it */
508 _dbus_marshal_set_uint32 (str, byte_order,
509 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
510 _dbus_string_get_length (str) - array_start);
515 /* Restore previous length */
516 _dbus_string_set_length (str, old_string_len);
523 * Demarshals a double.
525 * @param str the string containing the data
526 * @param byte_order the byte order
527 * @param pos the position in the string
528 * @param new_pos the new position of the string
529 * @returns the demarshaled double.
532 _dbus_demarshal_double (const DBusString *str,
540 pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
542 buffer = _dbus_string_get_const_data_len (str, pos, sizeof (double));
544 retval = *(double *)buffer;
546 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
547 swap_bytes ((unsigned char *)&retval, sizeof (double));
550 *new_pos = pos + sizeof (double);
556 * Demarshals a 32 bit signed integer.
558 * @param str the string containing the data
559 * @param byte_order the byte order
560 * @param pos the position in the string
561 * @param new_pos the new position of the string
562 * @returns the demarshaled integer.
565 _dbus_demarshal_int32 (const DBusString *str,
570 const DBusRealString *real = (const DBusRealString*) str;
572 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
575 *new_pos = pos + sizeof (dbus_int32_t);
577 if (byte_order == DBUS_LITTLE_ENDIAN)
578 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
580 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
584 * Demarshals a 32 bit unsigned integer.
586 * @param str the string containing the data
587 * @param byte_order the byte order
588 * @param pos the position in the string
589 * @param new_pos the new position of the string
590 * @returns the demarshaled integer.
593 _dbus_demarshal_uint32 (const DBusString *str,
598 const DBusRealString *real = (const DBusRealString*) str;
600 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
603 *new_pos = pos + sizeof (dbus_uint32_t);
605 if (byte_order == DBUS_LITTLE_ENDIAN)
606 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
608 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
612 * Demarshals an UTF-8 string.
614 * @todo Should we check the string to make sure
615 * that it's valid UTF-8, and maybe "fix" the string
618 * @todo Should probably demarshal to a DBusString,
619 * having memcpy() in here is Evil(tm).
621 * @param str the string containing the data
622 * @param byte_order the byte order
623 * @param pos the position in the string
624 * @param new_pos the new position of the string
625 * @returns the demarshaled string.
628 _dbus_demarshal_string (const DBusString *str,
637 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
639 retval = dbus_malloc (len + 1);
644 data = _dbus_string_get_const_data_len (str, pos, len + 1);
649 memcpy (retval, data, len + 1);
652 *new_pos = pos + len + 1;
658 * Demarshals a byte array.
660 * @todo Should probably demarshal to a DBusString,
661 * having memcpy() in here is Evil(tm).
663 * @param str the string containing the data
664 * @param byte_order the byte order
665 * @param pos the position in the string
666 * @param new_pos the new position of the string
667 * @param array the array
668 * @param array_len length of the demarshaled data
670 * @returns #TRUE on success
673 _dbus_demarshal_byte_array (const DBusString *str,
677 unsigned char **array,
681 unsigned char *retval;
684 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
697 retval = dbus_malloc (len);
702 data = _dbus_string_get_const_data_len (str, pos, len);
710 memcpy (retval, data, len);
713 *new_pos = pos + len;
722 * Demarshals a 32 bit signed integer array.
724 * @param str the string containing the data
725 * @param byte_order the byte order
726 * @param pos the position in the string
727 * @param new_pos the new position of the string
728 * @param array the array
729 * @param array_len length of the demarshaled data
730 * @returns #TRUE on success
733 _dbus_demarshal_int32_array (const DBusString *str,
737 dbus_int32_t **array,
741 dbus_int32_t *retval;
743 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_int32_t);
756 retval = dbus_new (dbus_int32_t, len);
761 for (i = 0; i < len; i++)
762 retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
774 * Demarshals a 32 bit unsigned integer array.
776 * @param str the string containing the data
777 * @param byte_order the byte order
778 * @param pos the position in the string
779 * @param new_pos the new position of the string
780 * @param array the array
781 * @param array_len length of the demarshaled data
782 * @returns #TRUE on success
785 _dbus_demarshal_uint32_array (const DBusString *str,
789 dbus_uint32_t **array,
793 dbus_uint32_t *retval;
795 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_uint32_t);
808 retval = dbus_new (dbus_uint32_t, len);
813 for (i = 0; i < len; i++)
814 retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
826 * Demarshals a double array.
828 * @param str the string containing the data
829 * @param byte_order the byte order
830 * @param pos the position in the string
831 * @param new_pos the new position of the string
832 * @param array the array
833 * @param array_len length of the demarshaled data
834 * @returns #TRUE on success
837 _dbus_demarshal_double_array (const DBusString *str,
847 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (double);
860 retval = dbus_new (double, len);
865 for (i = 0; i < len; i++)
866 retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
878 * Demarshals a string array.
880 * @param str the string containing the data
881 * @param byte_order the byte order
882 * @param pos the position in the string
883 * @param new_pos the new position of the string
884 * @param array the array
885 * @param array_len length of the demarshaled data
886 * @returns #TRUE on success
889 _dbus_demarshal_string_array (const DBusString *str,
899 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
912 retval = dbus_new (char *, len + 1);
919 for (i = 0; i < len; i++)
921 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
936 for (j = 0; j < i; j++)
937 dbus_free (retval[i]);
944 * Returns the position right after the end of an argument. PERFORMS
945 * NO VALIDATION WHATSOEVER. The message must have been previously
948 * @param str a string
949 * @param byte_order the byte order to use
950 * @param type the type of the argument
951 * @param pos the pos where the arg starts
952 * @param end_pos pointer where the position right
953 * after the end position will follow
954 * @returns TRUE if more data exists after the arg
957 _dbus_marshal_get_arg_end_pos (const DBusString *str,
963 if (pos >= _dbus_string_get_length (str))
968 case DBUS_TYPE_INVALID:
980 case DBUS_TYPE_BOOLEAN:
984 case DBUS_TYPE_INT32:
985 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
989 case DBUS_TYPE_UINT32:
990 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
994 case DBUS_TYPE_DOUBLE:
995 *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
999 case DBUS_TYPE_STRING:
1003 /* Demarshal the length */
1004 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1006 *end_pos = pos + len + 1;
1010 case DBUS_TYPE_NAMED:
1014 /* Demarshal the string length */
1015 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1017 *end_pos = pos + len + 1;
1019 /* Demarshal the data length */
1020 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1022 *end_pos = pos + len;
1026 case DBUS_TYPE_ARRAY:
1030 /* Demarshal the length (element type is at pos + 0 */
1031 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1033 *end_pos = pos + len;
1037 case DBUS_TYPE_DICT:
1041 /* Demarshal the length */
1042 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1044 *end_pos = pos + len;
1049 _dbus_warn ("Unknown message arg type %d\n", type);
1050 _dbus_assert_not_reached ("Unknown message argument type\n");
1054 if (*end_pos > _dbus_string_get_length (str))
1061 * Demarshals and validates a length; returns < 0 if the validation
1062 * fails. The length is required to be small enough that
1063 * len*sizeof(double) will not overflow, and small enough to fit in a
1064 * signed integer. DOES NOT check whether the length points
1065 * beyond the end of the string, because it doesn't know the
1066 * size of array elements.
1068 * @param str the string
1069 * @param byte_order the byte order
1070 * @param pos the unaligned string position (snap to next aligned)
1071 * @param new_pos return location for new position.
1074 demarshal_and_validate_len (const DBusString *str,
1079 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1082 _dbus_assert (new_pos != NULL);
1084 if ((align_4 + 4) > _dbus_string_get_length (str))
1086 _dbus_verbose ("not enough room in message for array length\n");
1090 if (!_dbus_string_validate_nul (str, pos,
1093 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1097 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1099 /* note that the len is the number of bytes, so we need it to be
1100 * at least SIZE_T_MAX, but make it smaller just to keep things
1101 * sane. We end up using ints for most sizes to avoid unsigned mess
1102 * so limit to maximum 32-bit signed int divided by at least 8, more
1103 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1105 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1106 if (len > MAX_ARRAY_LENGTH)
1108 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1109 len, MAX_ARRAY_LENGTH);
1117 validate_string (const DBusString *str,
1119 int len_without_nul,
1122 *end_pos = pos + len_without_nul + 1;
1124 if (*end_pos > _dbus_string_get_length (str))
1126 _dbus_verbose ("string length outside length of the message\n");
1130 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1132 _dbus_verbose ("string arg not nul-terminated\n");
1136 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1138 _dbus_verbose ("string is not valid UTF-8\n");
1146 * Validates and returns a typecode at a specific position
1149 * @param str a string
1150 * @param type the type of the argument
1151 * @param pos the pos where the typecode starts
1152 * @param end_pos pointer where the position right
1153 * after the end position will follow
1154 * @returns #TRUE if the type is valid.
1157 _dbus_marshal_validate_type (const DBusString *str,
1164 if (pos >= _dbus_string_get_length (str))
1167 data = _dbus_string_get_const_data_len (str, pos, 1);
1169 if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1181 * Validates an argument of a specific type, checking that it
1182 * is well-formed, for example no ludicrous length fields, strings
1183 * are nul-terminated, etc.
1184 * Returns the end position of the argument in end_pos, and
1185 * returns #TRUE if a valid arg begins at "pos"
1187 * @todo security: need to audit this function.
1189 * @todo For array types that can't be invalid, we should not
1190 * walk the whole array validating it. e.g. just skip all the
1191 * int values in an int array.
1193 * @param str a string
1194 * @param byte_order the byte order to use
1195 * @param depth current recursion depth, to prevent excessive recursion
1196 * @param type the type of the argument
1197 * @param pos the pos where the arg starts
1198 * @param end_pos pointer where the position right
1199 * after the end position will follow
1200 * @returns #TRUE if the arg is valid.
1203 _dbus_marshal_validate_arg (const DBusString *str,
1210 if (pos > _dbus_string_get_length (str))
1212 _dbus_verbose ("Validation went off the end of the message\n");
1216 #define MAX_VALIDATION_DEPTH 32
1218 if (depth > MAX_VALIDATION_DEPTH)
1220 _dbus_verbose ("Maximum recursion depth reached validating message\n");
1226 case DBUS_TYPE_INVALID:
1234 case DBUS_TYPE_BYTE:
1235 if (1 > _dbus_string_get_length (str) - pos)
1237 _dbus_verbose ("no room for byte value\n");
1244 case DBUS_TYPE_BOOLEAN:
1248 if (1 > _dbus_string_get_length (str) - pos)
1250 _dbus_verbose ("no room for boolean value\n");
1254 c = _dbus_string_get_byte (str, pos);
1256 if (c != 0 && c != 1)
1258 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1265 case DBUS_TYPE_INT32:
1266 case DBUS_TYPE_UINT32:
1268 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1270 if (!_dbus_string_validate_nul (str, pos,
1273 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1277 *end_pos = align_4 + 4;
1281 case DBUS_TYPE_DOUBLE:
1283 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1285 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1287 if (!_dbus_string_validate_nul (str, pos,
1290 _dbus_verbose ("double alignment padding not initialized to nul\n");
1294 *end_pos = align_8 + 8;
1298 case DBUS_TYPE_STRING:
1302 /* Demarshal the length, which does NOT include
1305 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1309 if (!validate_string (str, pos, len, end_pos))
1314 case DBUS_TYPE_NAMED:
1318 /* Demarshal the string length, which does NOT include
1321 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1325 if (!validate_string (str, pos, len, &pos))
1329 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1333 *end_pos = pos + len;
1337 case DBUS_TYPE_ARRAY:
1343 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1345 _dbus_verbose ("invalid array type\n");
1349 /* NIL values take up no space, so you couldn't iterate over an array of them.
1350 * array of nil seems useless anyway; the useful thing might be array of
1351 * (nil OR string) but we have no framework for that.
1353 if (array_type == DBUS_TYPE_NIL)
1355 _dbus_verbose ("array of NIL is not allowed\n");
1359 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1363 if (len > _dbus_string_get_length (str) - pos)
1365 _dbus_verbose ("array length outside length of the message\n");
1373 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1374 array_type, pos, &pos))
1380 /* This should not be able to happen, as long as validate_arg moves forward;
1381 * but the check is here just to be paranoid.
1383 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
1390 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
1398 case DBUS_TYPE_DICT:
1404 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1408 if (len > _dbus_string_get_length (str) - pos)
1410 _dbus_verbose ("dict length outside length of the message\n");
1419 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1420 DBUS_TYPE_STRING, pos, &pos))
1423 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
1425 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
1429 /* Validate element */
1430 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1431 dict_type, pos, &pos))
1437 _dbus_verbose ("dict contents exceed stated dict length\n");
1446 _dbus_verbose ("Unknown message arg type %d\n", type);
1450 if (*end_pos > _dbus_string_get_length (str))
1458 * If in verbose mode, print a block of binary data.
1460 * @todo right now it prints even if not in verbose mode
1462 * @param data the data
1463 * @param len the length of the data
1466 _dbus_verbose_bytes (const unsigned char *data,
1470 const unsigned char *aligned;
1472 _dbus_assert (len >= 0);
1474 /* Print blanks on first row if appropriate */
1475 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1478 _dbus_assert (aligned <= data);
1480 if (aligned != data)
1482 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1483 while (aligned != data)
1485 _dbus_verbose (" ");
1490 /* now print the bytes */
1494 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1496 _dbus_verbose ("%4d\t%p: ",
1500 if (data[i] >= 32 &&
1502 _dbus_verbose (" '%c' ", data[i]);
1504 _dbus_verbose ("0x%s%x ",
1505 data[i] <= 0xf ? "0" : "", data[i]);
1509 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1512 _dbus_verbose ("BE: %d LE: %d",
1513 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1514 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1517 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1519 _dbus_verbose (" dbl: %g",
1520 *(double*)&data[i-8]);
1523 _dbus_verbose ("\n");
1527 _dbus_verbose ("\n");
1531 * Dump the given part of the string to verbose log.
1533 * @param str the string
1534 * @param start the start of range to dump
1535 * @param len length of range
1538 _dbus_verbose_bytes_of_string (const DBusString *str,
1545 real_len = _dbus_string_get_length (str);
1547 _dbus_assert (start >= 0);
1549 if (start > real_len)
1551 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1552 start, len, real_len);
1556 if ((start + len) > real_len)
1558 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1559 start, len, real_len);
1560 len = real_len - start;
1563 d = _dbus_string_get_const_data_len (str, start, len);
1565 _dbus_verbose_bytes (d, len);
1570 #ifdef DBUS_BUILD_TESTS
1571 #include "dbus-test.h"
1575 _dbus_marshal_test (void)
1579 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1582 if (!_dbus_string_init (&str))
1583 _dbus_assert_not_reached ("failed to init string");
1585 /* Marshal doubles */
1586 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1587 _dbus_assert_not_reached ("could not marshal double value");
1588 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1589 _dbus_assert_not_reached ("demarshal failed");
1591 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1592 _dbus_assert_not_reached ("could not marshal double value");
1593 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1594 _dbus_assert_not_reached ("demarshal failed");
1596 /* Marshal signed integers */
1597 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1598 _dbus_assert_not_reached ("could not marshal signed integer value");
1599 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1600 _dbus_assert_not_reached ("demarshal failed");
1602 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1603 _dbus_assert_not_reached ("could not marshal signed integer value");
1604 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1605 _dbus_assert_not_reached ("demarshal failed");
1607 /* Marshal unsigned integers */
1608 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1609 _dbus_assert_not_reached ("could not marshal signed integer value");
1610 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1611 _dbus_assert_not_reached ("demarshal failed");
1613 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1614 _dbus_assert_not_reached ("could not marshal signed integer value");
1615 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1616 _dbus_assert_not_reached ("demarshal failed");
1618 /* Marshal strings */
1619 tmp1 = "This is the dbus test string";
1620 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1621 _dbus_assert_not_reached ("could not marshal string");
1622 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1623 if (!strcmp (tmp1, tmp2) == 0)
1624 _dbus_assert_not_reached ("demarshal failed");
1627 tmp1 = "This is the dbus test string";
1628 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1629 _dbus_assert_not_reached ("could not marshal string");
1630 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1631 if (!strcmp (tmp1, tmp2) == 0)
1632 _dbus_assert_not_reached ("demarshal failed");
1635 /* Marshal signed integer arrays */
1636 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1637 _dbus_assert_not_reached ("could not marshal integer array");
1638 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
1639 _dbus_assert_not_reached ("could not demarshal integer array");
1642 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1645 _dbus_string_free (&str);
1651 #endif /* DBUS_BUILD_TESTS */