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 _dbus_string_get_data_len (str, &data, 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 _dbus_string_get_data_len (str, &data, 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 * @param str the string to append the marshalled value to
302 * @param byte_order the byte order to use
303 * @param value the string
304 * @returns #TRUE on success
307 _dbus_marshal_string (DBusString *str,
311 int len, old_string_len;
313 old_string_len = _dbus_string_get_length (str);
315 len = strlen (value);
317 if (!_dbus_marshal_uint32 (str, byte_order, len))
319 /* Restore the previous length */
320 _dbus_string_set_length (str, old_string_len);
325 return _dbus_string_append_len (str, value, len + 1);
329 * Marshals a byte array
331 * @param str the string to append the marshalled value to
332 * @param byte_order the byte order to use
333 * @param value the array
334 * @param len number of elements in the array
335 * @returns #TRUE on success
338 _dbus_marshal_byte_array (DBusString *str,
340 const unsigned char *value,
345 old_string_len = _dbus_string_get_length (str);
347 if (!_dbus_marshal_uint32 (str, byte_order, len))
349 /* Restore the previous length */
350 _dbus_string_set_length (str, old_string_len);
358 return _dbus_string_append_len (str, value, len);
362 * Marshals a 32 bit signed integer array
364 * @param str the string to append the marshalled value to
365 * @param byte_order the byte order to use
366 * @param value the array
367 * @param len the length of the array
368 * @returns #TRUE on success
371 _dbus_marshal_int32_array (DBusString *str,
373 const dbus_int32_t *value,
376 int i, old_string_len;
378 old_string_len = _dbus_string_get_length (str);
380 if (!_dbus_marshal_uint32 (str, byte_order, len))
383 for (i = 0; i < len; i++)
384 if (!_dbus_marshal_int32 (str, byte_order, value[i]))
390 /* Restore previous length */
391 _dbus_string_set_length (str, old_string_len);
397 * Marshals a 32 bit unsigned integer array
399 * @param str the string to append the marshalled value to
400 * @param byte_order the byte order to use
401 * @param value the array
402 * @param len the length of the array
403 * @returns #TRUE on success
406 _dbus_marshal_uint32_array (DBusString *str,
408 const dbus_uint32_t *value,
411 int i, old_string_len;
413 old_string_len = _dbus_string_get_length (str);
415 if (!_dbus_marshal_uint32 (str, byte_order, len))
418 for (i = 0; i < len; i++)
419 if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
425 /* Restore previous length */
426 _dbus_string_set_length (str, old_string_len);
432 * Marshals a double array
434 * @param str the string to append the marshalled value to
435 * @param byte_order the byte order to use
436 * @param value the array
437 * @param len the length of the array
438 * @returns #TRUE on success
441 _dbus_marshal_double_array (DBusString *str,
446 int i, old_string_len;
448 old_string_len = _dbus_string_get_length (str);
450 if (!_dbus_marshal_uint32 (str, byte_order, len))
453 for (i = 0; i < len; i++)
454 if (!_dbus_marshal_double (str, byte_order, value[i]))
460 /* Restore previous length */
461 _dbus_string_set_length (str, old_string_len);
467 * Marshals a string array
469 * @param str the string to append the marshalled value to
470 * @param byte_order the byte order to use
471 * @param value the array
472 * @param len the length of the array
473 * @returns #TRUE on success
476 _dbus_marshal_string_array (DBusString *str,
481 int i, old_string_len;
483 old_string_len = _dbus_string_get_length (str);
485 if (!_dbus_marshal_uint32 (str, byte_order, len))
488 for (i = 0; i < len; i++)
489 if (!_dbus_marshal_string (str, byte_order, value[i]))
495 /* Restore previous length */
496 _dbus_string_set_length (str, old_string_len);
504 * @param str the string to append the marshalled value to
505 * @param byte_order the byte order to use
506 * @param dict the dict
507 * @returns #TRUE on success
510 _dbus_marshal_dict (DBusString *str,
518 old_string_len = _dbus_string_get_length (str);
520 if (!dbus_dict_get_keys (dict, &keys, &len))
526 if (!_dbus_marshal_string_array (str, byte_order,
527 (const char **)keys, len))
530 for (i = 0; i < len; i++)
534 value_type = dbus_dict_get_value_type (dict, keys[i]);
536 if (!_dbus_string_append_byte (str, value_type))
539 switch (dbus_dict_get_value_type (dict, keys[i]))
541 case DBUS_TYPE_BOOLEAN:
545 if (!dbus_dict_get_boolean (dict, keys[i], &value))
548 if (!_dbus_string_append_byte (str, (value != FALSE)))
554 case DBUS_TYPE_INT32:
558 if (!dbus_dict_get_int32 (dict, keys[i], &value))
561 if (!_dbus_marshal_int32 (str, byte_order, value))
566 case DBUS_TYPE_UINT32:
570 if (!dbus_dict_get_uint32 (dict, keys[i], &value))
573 if (!_dbus_marshal_uint32 (str, byte_order, value))
578 case DBUS_TYPE_DOUBLE:
582 if (!dbus_dict_get_double (dict, keys[i], &value))
585 if (!_dbus_marshal_double (str, byte_order, value))
590 case DBUS_TYPE_INT32_ARRAY:
592 const dbus_int32_t *value;
595 if (!dbus_dict_get_int32_array (dict, keys[i], &value, &len))
598 if (!_dbus_marshal_int32_array (str, byte_order, value, len))
603 case DBUS_TYPE_STRING:
607 if (!dbus_dict_get_string (dict, keys[i], &value))
610 if (!_dbus_marshal_string (str, byte_order, value))
615 case DBUS_TYPE_BOOLEAN_ARRAY:
617 const unsigned char *value;
620 if (!dbus_dict_get_boolean_array (dict, keys[i], &value, &len))
623 if (!_dbus_marshal_byte_array (str, byte_order, value, len))
628 case DBUS_TYPE_UINT32_ARRAY:
630 const dbus_uint32_t *value;
633 if (!dbus_dict_get_uint32_array (dict, keys[i], &value, &len))
636 if (!_dbus_marshal_uint32_array (str, byte_order, value, len))
641 case DBUS_TYPE_DOUBLE_ARRAY:
646 if (!dbus_dict_get_double_array (dict, keys[i], &value, &len))
649 if (!_dbus_marshal_double_array (str, byte_order, value, len))
654 case DBUS_TYPE_STRING_ARRAY:
659 if (!dbus_dict_get_string_array (dict, keys[i], &value, &len))
662 if (!_dbus_marshal_string_array (str, byte_order, (const char **)value, len))
668 _dbus_warn ("unkown value type %d\n", dbus_dict_get_value_type (dict, keys[i]));
669 _dbus_assert_not_reached ("unknown value type in dict");
673 dbus_free_string_array (keys);
679 dbus_free_string_array (keys);
681 /* Restore previous length */
682 _dbus_string_set_length (str, old_string_len);
689 * Demarshals a double.
691 * @param str the string containing the data
692 * @param byte_order the byte order
693 * @param pos the position in the string
694 * @param new_pos the new position of the string
695 * @returns the demarshaled double.
698 _dbus_demarshal_double (const DBusString *str,
706 pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
708 _dbus_string_get_const_data_len (str, &buffer, pos, sizeof (double));
710 retval = *(double *)buffer;
712 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
713 swap_bytes ((unsigned char *)&retval, sizeof (double));
716 *new_pos = pos + sizeof (double);
722 * Demarshals a 32 bit signed integer.
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 * @returns the demarshaled integer.
731 _dbus_demarshal_int32 (const DBusString *str,
736 const DBusRealString *real = (const DBusRealString*) str;
738 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
741 *new_pos = pos + sizeof (dbus_int32_t);
743 if (byte_order == DBUS_LITTLE_ENDIAN)
744 return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
746 return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
750 * Demarshals a 32 bit unsigned integer.
752 * @param str the string containing the data
753 * @param byte_order the byte order
754 * @param pos the position in the string
755 * @param new_pos the new position of the string
756 * @returns the demarshaled integer.
759 _dbus_demarshal_uint32 (const DBusString *str,
764 const DBusRealString *real = (const DBusRealString*) str;
766 pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
769 *new_pos = pos + sizeof (dbus_uint32_t);
771 if (byte_order == DBUS_LITTLE_ENDIAN)
772 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
774 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
778 * Demarshals an UTF-8 string.
780 * @todo Should we check the string to make sure
781 * that it's valid UTF-8, and maybe "fix" the string
784 * @todo Should probably demarshal to a DBusString,
785 * having memcpy() in here is Evil(tm).
787 * @param str the string containing the data
788 * @param byte_order the byte order
789 * @param pos the position in the string
790 * @param new_pos the new position of the string
791 * @returns the demarshaled string.
794 _dbus_demarshal_string (const DBusString *str,
803 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
805 retval = dbus_malloc (len + 1);
810 _dbus_string_get_const_data_len (str, &data, pos, len);
815 memcpy (retval, data, len + 1);
818 *new_pos = pos + len + 1;
824 * Demarshals a byte array.
826 * @todo Should probably demarshal to a DBusString,
827 * having memcpy() in here is Evil(tm).
829 * @param str the string containing the data
830 * @param byte_order the byte order
831 * @param pos the position in the string
832 * @param new_pos the new position of the string
833 * @param array the array
834 * @param array_len length of the demarshaled data
836 * @returns #TRUE on success
839 _dbus_demarshal_byte_array (const DBusString *str,
843 unsigned char **array,
847 unsigned char *retval;
850 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
863 retval = dbus_malloc (len);
868 _dbus_string_get_const_data_len (str, &data, pos, len);
876 memcpy (retval, data, len);
879 *new_pos = pos + len;
888 * Demarshals a 32 bit signed integer array.
890 * @param str the string containing the data
891 * @param byte_order the byte order
892 * @param pos the position in the string
893 * @param new_pos the new position of the string
894 * @param array the array
895 * @param array_len length of the demarshaled data
896 * @returns #TRUE on success
899 _dbus_demarshal_int32_array (const DBusString *str,
903 dbus_int32_t **array,
907 dbus_int32_t *retval;
909 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
922 retval = dbus_new (dbus_int32_t, len);
927 for (i = 0; i < len; i++)
928 retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
940 * Demarshals a 32 bit unsigned integer array.
942 * @param str the string containing the data
943 * @param byte_order the byte order
944 * @param pos the position in the string
945 * @param new_pos the new position of the string
946 * @param array the array
947 * @param array_len length of the demarshaled data
948 * @returns #TRUE on success
951 _dbus_demarshal_uint32_array (const DBusString *str,
955 dbus_uint32_t **array,
959 dbus_uint32_t *retval;
961 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
974 retval = dbus_new (dbus_uint32_t, len);
979 for (i = 0; i < len; i++)
980 retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
992 * Demarshals a double array.
994 * @param str the string containing the data
995 * @param byte_order the byte order
996 * @param pos the position in the string
997 * @param new_pos the new position of the string
998 * @param array the array
999 * @param array_len length of the demarshaled data
1000 * @returns #TRUE on success
1003 _dbus_demarshal_double_array (const DBusString *str,
1013 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1026 retval = dbus_new (double, len);
1031 for (i = 0; i < len; i++)
1032 retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
1044 * Demarshals a string array.
1046 * @param str the string containing the data
1047 * @param byte_order the byte order
1048 * @param pos the position in the string
1049 * @param new_pos the new position of the string
1050 * @param array the array
1051 * @param array_len length of the demarshaled data
1052 * @returns #TRUE on success
1055 _dbus_demarshal_string_array (const DBusString *str,
1065 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1078 retval = dbus_new (char *, len + 1);
1085 for (i = 0; i < len; i++)
1087 retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
1102 for (j = 0; j < i; j++)
1103 dbus_free (retval[i]);
1112 * @param str the string containing the data
1113 * @param byte_order the byte order
1114 * @param pos the position in the string
1115 * @param new_pos the new position in the string
1116 * @param dict the dict
1117 * @returns #TRUE on success.
1120 _dbus_demarshal_dict (const DBusString *str,
1129 *dict = dbus_dict_new ();
1133 if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &keys, &len))
1136 for (i = 0; i < len; i++)
1140 switch ((value_type = _dbus_string_get_byte (str, pos ++)))
1142 case DBUS_TYPE_BOOLEAN:
1146 value = _dbus_string_get_byte (str, pos ++);
1148 if (!dbus_dict_set_boolean (*dict, keys[i], value))
1152 case DBUS_TYPE_INT32:
1156 value = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
1158 if (!dbus_dict_set_int32 (*dict, keys[i], value))
1163 case DBUS_TYPE_UINT32:
1165 dbus_uint32_t value;
1167 value = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1169 if (!dbus_dict_set_uint32 (*dict, keys[i], value))
1174 case DBUS_TYPE_DOUBLE:
1178 value = _dbus_demarshal_double (str, byte_order, pos, &pos);
1180 if (!dbus_dict_set_double (*dict, keys[i], value))
1185 case DBUS_TYPE_STRING:
1189 value = _dbus_demarshal_string (str, byte_order, pos, &pos);
1194 if (!dbus_dict_set_string (*dict, keys[i], value))
1204 case DBUS_TYPE_BOOLEAN_ARRAY:
1206 unsigned char *value;
1209 if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1212 if (!dbus_dict_set_boolean_array (*dict, keys[i], value, len))
1221 case DBUS_TYPE_INT32_ARRAY:
1223 dbus_int32_t *value;
1226 if (!_dbus_demarshal_int32_array (str, byte_order, pos, &pos, &value, &len))
1229 if (!dbus_dict_set_int32_array (*dict, keys[i], value, len))
1238 case DBUS_TYPE_UINT32_ARRAY:
1240 dbus_uint32_t *value;
1243 if (!_dbus_demarshal_uint32_array (str, byte_order, pos, &pos, &value, &len))
1246 if (!dbus_dict_set_uint32_array (*dict, keys[i], value, len))
1255 case DBUS_TYPE_DOUBLE_ARRAY:
1260 if (!_dbus_demarshal_double_array (str, byte_order, pos, &pos, &value, &len))
1263 if (!dbus_dict_set_double_array (*dict, keys[i], value, len))
1272 case DBUS_TYPE_BYTE_ARRAY:
1274 unsigned char *value;
1277 if (!_dbus_demarshal_byte_array (str, byte_order, pos, &pos, &value, &len))
1280 if (!dbus_dict_set_byte_array (*dict, keys[i], value, len))
1289 case DBUS_TYPE_STRING_ARRAY:
1294 if (!_dbus_demarshal_string_array (str, byte_order, pos, &pos, &value, &len))
1297 if (!dbus_dict_set_string_array (*dict, keys[i], (const char **)value, len))
1299 dbus_free_string_array (value);
1303 dbus_free_string_array (value);
1307 _dbus_warn ("unknown value type %d\n", value_type);
1308 _dbus_assert_not_reached ("unknown value arg");
1312 dbus_free_string_array (keys);
1316 dbus_free_string_array (keys);
1317 dbus_dict_unref (*dict);
1323 * Returns the position right after the end of an argument. PERFORMS
1324 * NO VALIDATION WHATSOEVER. The message must have been previously
1327 * @param str a string
1328 * @param byte_order the byte order to use
1329 * @param pos the pos where the arg starts
1330 * @param end_pos pointer where the position right
1331 * after the end position will follow
1332 * @returns TRUE if more data exists after the arg
1335 _dbus_marshal_get_arg_end_pos (const DBusString *str,
1342 if (pos >= _dbus_string_get_length (str))
1345 _dbus_string_get_const_data_len (str, &data, pos, 1);
1349 case DBUS_TYPE_INVALID:
1357 case DBUS_TYPE_BOOLEAN:
1361 case DBUS_TYPE_INT32:
1362 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
1366 case DBUS_TYPE_UINT32:
1367 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
1371 case DBUS_TYPE_DOUBLE:
1372 *end_pos = _DBUS_ALIGN_VALUE (pos + 1, sizeof (double)) + sizeof (double);
1376 case DBUS_TYPE_STRING:
1380 /* Demarshal the length */
1381 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1383 *end_pos = pos + len + 1;
1387 case DBUS_TYPE_BOOLEAN_ARRAY:
1388 case DBUS_TYPE_BYTE_ARRAY:
1392 /* Demarshal the length */
1393 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1395 *end_pos = pos + len;
1399 case DBUS_TYPE_INT32_ARRAY:
1403 /* Demarshal the length */
1404 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1406 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_int32_t))
1407 + (len * sizeof (dbus_int32_t));
1411 case DBUS_TYPE_UINT32_ARRAY:
1415 /* Demarshal the length */
1416 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1418 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (dbus_uint32_t))
1419 + (len * sizeof (dbus_uint32_t));
1423 case DBUS_TYPE_DOUBLE_ARRAY:
1427 /* Demarshal the length */
1428 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &new_pos);
1430 *end_pos = _DBUS_ALIGN_VALUE (new_pos, sizeof (double))
1431 + (len * sizeof (double));
1435 case DBUS_TYPE_STRING_ARRAY:
1439 /* Demarshal the length */
1440 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1442 for (i = 0; i < len; i++)
1446 /* Demarshal string length */
1447 str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1455 case DBUS_TYPE_DICT:
1459 /* Demarshal the length */
1460 len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1462 for (i = 0; i < len; i++)
1466 /* Demarshal string length */
1467 str_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1471 /* Now check the values */
1472 for (i = 0; i < len; i++)
1474 if (!_dbus_marshal_get_arg_end_pos (str, byte_order, pos, &pos))
1483 _dbus_warn ("Unknown message arg type %d\n", *data);
1484 _dbus_assert_not_reached ("Unknown message argument type\n");
1488 if (*end_pos > _dbus_string_get_length (str))
1495 * Demarshals and validates a length; returns < 0 if the validation
1496 * fails. The length is required to be small enough that
1497 * len*sizeof(double) will not overflow, and small enough to fit in a
1498 * signed integer. DOES NOT check whether the length points
1499 * beyond the end of the string, because it doesn't know the
1500 * size of array elements.
1502 * @param str the string
1503 * @param byte_order the byte order
1504 * @param pos the unaligned string position (snap to next aligned)
1505 * @param new_pos return location for new position.
1508 demarshal_and_validate_len (const DBusString *str,
1513 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1516 _dbus_assert (new_pos != NULL);
1518 if ((align_4 + 4) > _dbus_string_get_length (str))
1520 _dbus_verbose ("not enough room in message for array length\n");
1524 if (!_dbus_string_validate_nul (str, pos,
1527 _dbus_verbose ("array length alignment padding not initialized to nul\n");
1531 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1533 /* note that the len may be a number of doubles, so we need it to be
1534 * at least SIZE_T_MAX / 8, but make it smaller just to keep things
1535 * sane. We end up using ints for most sizes to avoid unsigned mess
1536 * so limit to maximum 32-bit signed int divided by at least 8, more
1537 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1539 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1540 if (len > MAX_ARRAY_LENGTH)
1542 _dbus_verbose ("array length %u exceeds maximum of %u\n",
1543 len, MAX_ARRAY_LENGTH);
1551 validate_string (const DBusString *str,
1553 int len_without_nul,
1556 *end_pos = pos + len_without_nul + 1;
1558 if (*end_pos > _dbus_string_get_length (str))
1560 _dbus_verbose ("string length outside length of the message\n");
1564 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1566 _dbus_verbose ("string arg not nul-terminated\n");
1570 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1572 _dbus_verbose ("string is not valid UTF-8\n");
1580 * Validates an argument, checking that it is well-formed, for example
1581 * no ludicrous length fields, strings are nul-terminated, etc.
1582 * Returns the end position of the argument in end_pos, and
1583 * returns #TRUE if a valid arg begins at "pos"
1585 * @todo security: need to audit this function.
1587 * @param str a string
1588 * @param byte_order the byte order to use
1589 * @param pos the pos where the arg starts (offset of its typecode)
1590 * @param end_pos pointer where the position right
1591 * after the end position will follow
1592 * @returns #TRUE if the arg is valid.
1595 _dbus_marshal_validate_arg (const DBusString *str,
1602 if (pos >= _dbus_string_get_length (str))
1605 _dbus_string_get_const_data_len (str, &data, pos, 1);
1609 case DBUS_TYPE_INVALID:
1617 case DBUS_TYPE_BOOLEAN:
1621 if (2 > _dbus_string_get_length (str) - pos)
1623 _dbus_verbose ("no room for boolean value\n");
1627 c = _dbus_string_get_byte (str, pos + 1);
1629 if (c != 0 && c != 1)
1631 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1638 case DBUS_TYPE_INT32:
1639 case DBUS_TYPE_UINT32:
1641 int align_4 = _DBUS_ALIGN_VALUE (pos + 1, 4);
1643 if (!_dbus_string_validate_nul (str, pos + 1,
1646 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1650 *end_pos = align_4 + 4;
1654 case DBUS_TYPE_DOUBLE:
1656 int align_8 = _DBUS_ALIGN_VALUE (pos + 1, 8);
1658 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1660 if (!_dbus_string_validate_nul (str, pos + 1,
1663 _dbus_verbose ("double alignment padding not initialized to nul\n");
1667 *end_pos = align_8 + 8;
1671 case DBUS_TYPE_STRING:
1675 /* Demarshal the length, which does NOT include
1678 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1682 if (!validate_string (str, pos, len, end_pos))
1687 case DBUS_TYPE_BOOLEAN_ARRAY:
1691 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1695 if (len > _dbus_string_get_length (str) - pos)
1697 _dbus_verbose ("boolean array length outside length of the message\n");
1704 unsigned char c = _dbus_string_get_byte (str, pos + i);
1706 if (c != 0 && c != 1)
1708 _dbus_verbose ("boolean value must be either 0 or 1, not %d (pos %d)\n", c, pos);
1714 *end_pos = pos + len;
1717 case DBUS_TYPE_BYTE_ARRAY:
1721 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1725 *end_pos = pos + len;
1729 case DBUS_TYPE_INT32_ARRAY:
1730 case DBUS_TYPE_UINT32_ARRAY:
1734 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1738 _dbus_assert (_DBUS_ALIGN_VALUE (pos, 4) == (unsigned int) pos);
1740 *end_pos = pos + len * 4;
1744 case DBUS_TYPE_DOUBLE_ARRAY:
1749 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1757 align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1758 if (!_dbus_string_validate_nul (str, pos,
1761 _dbus_verbose ("double array alignment padding not initialized to nul\n");
1765 *end_pos = align_8 + len * 8;
1770 case DBUS_TYPE_STRING_ARRAY:
1775 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1779 for (i = 0; i < len; i++)
1783 str_len = demarshal_and_validate_len (str, byte_order,
1788 if (!validate_string (str, pos, str_len, &pos))
1796 case DBUS_TYPE_DICT:
1801 len = demarshal_and_validate_len (str, byte_order, pos + 1, &pos);
1805 for (i = 0; i < len; i++)
1809 str_len = demarshal_and_validate_len (str, byte_order,
1814 if (!validate_string (str, pos, str_len, &pos))
1818 /* Now validate each argument */
1819 for (i = 0; i < len; i++)
1821 if (pos >= _dbus_string_get_length (str))
1823 _dbus_verbose ("not enough values in dict\n");
1827 if (_dbus_string_get_byte (str, pos) == DBUS_TYPE_NIL)
1829 _dbus_verbose ("can't have NIL values in dicts\n");
1833 if (!_dbus_marshal_validate_arg (str, byte_order, pos, &pos))
1843 _dbus_verbose ("Unknown message arg type %d\n", *data);
1847 if (*end_pos > _dbus_string_get_length (str))
1855 * If in verbose mode, print a block of binary data.
1857 * @todo right now it prints even if not in verbose mode
1859 * @param data the data
1860 * @param len the length of the data
1863 _dbus_verbose_bytes (const unsigned char *data,
1867 const unsigned char *aligned;
1869 _dbus_assert (len >= 0);
1871 /* Print blanks on first row if appropriate */
1872 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1875 _dbus_assert (aligned <= data);
1877 if (aligned != data)
1879 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
1880 while (aligned != data)
1882 _dbus_verbose (" ");
1887 /* now print the bytes */
1891 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1893 _dbus_verbose ("%4d\t%p: ",
1897 if (data[i] >= 32 &&
1899 _dbus_verbose (" '%c' ", data[i]);
1901 _dbus_verbose ("0x%s%x ",
1902 data[i] <= 0xf ? "0" : "", data[i]);
1906 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1909 _dbus_verbose ("BE: %d LE: %d",
1910 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1911 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1914 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1916 _dbus_verbose (" dbl: %g",
1917 *(double*)&data[i-8]);
1920 _dbus_verbose ("\n");
1924 _dbus_verbose ("\n");
1928 * Dump the given part of the string to verbose log.
1930 * @param str the string
1931 * @param start the start of range to dump
1932 * @param len length of range
1935 _dbus_verbose_bytes_of_string (const DBusString *str,
1942 real_len = _dbus_string_get_length (str);
1944 _dbus_assert (start >= 0);
1946 if (start > real_len)
1948 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
1949 start, len, real_len);
1953 if ((start + len) > real_len)
1955 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
1956 start, len, real_len);
1957 len = real_len - start;
1961 _dbus_string_get_const_data_len (str, &d, start, len);
1963 _dbus_verbose_bytes (d, len);
1968 #ifdef DBUS_BUILD_TESTS
1969 #include "dbus-test.h"
1973 _dbus_marshal_test (void)
1977 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1978 int pos = 0, i, len;
1979 dbus_bool_t our_bool;
1980 dbus_int32_t our_int;
1981 dbus_uint32_t our_uint;
1983 const char *our_string;
1984 const unsigned char boolean_array[] = { TRUE, FALSE, FALSE, TRUE };
1985 const unsigned char *our_boolean_array;
1986 const dbus_int32_t int32_array[] = { 0x12345678, -1911, 0, 0xaffe, 0xedd1e };
1987 const dbus_int32_t *our_int32_array;
1988 const dbus_uint32_t uint32_array[] = { 0x12345678, 0, 0xdeadbeef, 0x87654321, 0xffffffff };
1989 const dbus_uint32_t *our_uint32_array;
1990 const double double_array[] = { 3.14159, 1.2345, 6.7890 };
1991 const double *our_double_array;
1992 const char *string_array[] = { "This", "Is", "A", "Test" };
1993 const char **our_string_array;
1996 if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1997 _dbus_assert_not_reached ("failed to init string");
1999 /* Marshal doubles */
2000 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
2001 _dbus_assert_not_reached ("could not marshal double value");
2002 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
2003 _dbus_assert_not_reached ("demarshal failed");
2005 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
2006 _dbus_assert_not_reached ("could not marshal double value");
2007 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
2008 _dbus_assert_not_reached ("demarshal failed");
2010 /* Marshal signed integers */
2011 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
2012 _dbus_assert_not_reached ("could not marshal signed integer value");
2013 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
2014 _dbus_assert_not_reached ("demarshal failed");
2016 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
2017 _dbus_assert_not_reached ("could not marshal signed integer value");
2018 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
2019 _dbus_assert_not_reached ("demarshal failed");
2021 /* Marshal unsigned integers */
2022 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
2023 _dbus_assert_not_reached ("could not marshal signed integer value");
2024 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
2025 _dbus_assert_not_reached ("demarshal failed");
2027 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
2028 _dbus_assert_not_reached ("could not marshal signed integer value");
2029 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
2030 _dbus_assert_not_reached ("demarshal failed");
2032 /* Marshal strings */
2033 tmp1 = "This is the dbus test string";
2034 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
2035 _dbus_assert_not_reached ("could not marshal string");
2036 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
2037 if (!strcmp (tmp1, tmp2) == 0)
2038 _dbus_assert_not_reached ("demarshal failed");
2041 tmp1 = "This is the dbus test string";
2042 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
2043 _dbus_assert_not_reached ("could not marshal string");
2044 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
2045 if (!strcmp (tmp1, tmp2) == 0)
2046 _dbus_assert_not_reached ("demarshal failed");
2049 /* Marshal signed integer arrays */
2050 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
2051 _dbus_assert_not_reached ("could not marshal integer array");
2052 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
2053 _dbus_assert_not_reached ("could not demarshal integer array");
2056 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
2061 dict = dbus_dict_new ();
2063 if (dbus_dict_get_value_type (dict, "foo") != DBUS_TYPE_NIL)
2064 _dbus_assert_not_reached ("didn't return DBUS_TYPE_NIL for non-existant entry");
2066 if (!dbus_dict_set_boolean (dict, "boolean", TRUE))
2067 _dbus_assert_not_reached ("could not add boolean value");
2069 if (!dbus_dict_set_int32 (dict, "int32", 0x12345678))
2070 _dbus_assert_not_reached ("could not add int32 value");
2072 if (!dbus_dict_set_uint32 (dict, "uint32", 0x87654321))
2073 _dbus_assert_not_reached ("could not add uint32 value");
2075 if (!dbus_dict_set_double (dict, "double", 3.14159))
2076 _dbus_assert_not_reached ("could not add double value");
2078 if (!dbus_dict_set_string (dict, "string", "test string"))
2079 _dbus_assert_not_reached ("could not add string value");
2081 if (!dbus_dict_set_boolean_array (dict, "boolean_array", boolean_array, 4))
2082 _dbus_assert_not_reached ("could not add boolean array");
2084 if (!dbus_dict_set_int32_array (dict, "int32_array", int32_array, 5))
2085 _dbus_assert_not_reached ("could not add int32 array");
2087 if (!dbus_dict_set_uint32_array (dict, "uint32_array", uint32_array, 5))
2088 _dbus_assert_not_reached ("could not add uint32 array");
2090 if (!dbus_dict_set_double_array (dict, "double_array", double_array, 3))
2091 _dbus_assert_not_reached ("could not add double array");
2093 if (!dbus_dict_set_string_array (dict, "string_array", string_array, 4))
2094 _dbus_assert_not_reached ("could not add string array");
2096 if (!_dbus_marshal_dict (&str, DBUS_BIG_ENDIAN, dict))
2097 _dbus_assert_not_reached ("could not marshal dict");
2099 dbus_dict_unref (dict);
2101 if (!_dbus_demarshal_dict (&str, DBUS_BIG_ENDIAN, pos, &pos, &dict))
2102 _dbus_assert_not_reached ("could not demarshal dict");
2104 if (!dbus_dict_get_boolean (dict, "boolean", &our_bool) ||
2106 _dbus_assert_not_reached ("could not get boolean value");
2108 if (!dbus_dict_get_int32 (dict, "int32", &our_int) || our_int != 0x12345678)
2109 _dbus_assert_not_reached ("could not get int32 value or int32 values differ");
2111 if (!dbus_dict_get_uint32 (dict, "uint32", &our_uint) || our_uint != 0x87654321)
2112 _dbus_assert_not_reached ("could not get uint32 value or uint32 values differ");
2114 if (!dbus_dict_get_double (dict, "double", &our_double)
2115 || our_double != 3.14159)
2116 _dbus_assert_not_reached ("could not get double value or double values differ");
2118 if (!dbus_dict_get_string (dict, "string", &our_string) || strcmp (our_string, "test string") != 0)
2119 _dbus_assert_not_reached ("could not get string value or string values differ");
2121 if (!dbus_dict_get_boolean_array (dict, "boolean_array", &our_boolean_array, &len) ||
2122 len != 4 || memcmp (boolean_array, our_boolean_array, 4) != 0)
2123 _dbus_assert_not_reached ("could not get boolean array value or boolean array values differ");
2125 if (!dbus_dict_get_int32_array (dict, "int32_array", &our_int32_array, &len) ||
2126 len != 5 || memcmp (int32_array, our_int32_array, 5 * sizeof (dbus_int32_t)) != 0)
2127 _dbus_assert_not_reached ("could not get int32 array value or int32 array values differ");
2129 if (!dbus_dict_get_uint32_array (dict, "uint32_array", &our_uint32_array, &len) ||
2130 len != 5 || memcmp (uint32_array, our_uint32_array, 5 * sizeof (dbus_uint32_t) ) != 0)
2131 _dbus_assert_not_reached ("could not get uint32 array value or uint32 array values differ");
2133 if (!dbus_dict_get_double_array (dict, "double_array", &our_double_array, &len) ||
2134 len != 3 || memcmp (double_array, our_double_array, 3 * sizeof (double)) != 0)
2135 _dbus_assert_not_reached ("could not get double array value or double array values differ");
2137 if (!dbus_dict_get_string_array (dict, "string_array", &our_string_array, &len))
2138 _dbus_assert_not_reached ("could not get string array value");
2141 _dbus_assert_not_reached ("string array lengths differ");
2143 for (i = 0; i < len; i++)
2145 if (strcmp (our_string_array[i], string_array[i]) != 0)
2146 _dbus_assert_not_reached ("string array fields differ");
2149 dbus_dict_unref (dict);
2151 _dbus_string_free (&str);
2157 #endif /* DBUS_BUILD_TESTS */