00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dbus-marshal.h"
00026 #include "dbus-internals.h"
00027 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00028 #include "dbus-string-private.h"
00029
00030 #include <string.h>
00031
00043 static dbus_uint32_t
00044 unpack_4_octets (int byte_order,
00045 const unsigned char *data)
00046 {
00047 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00048
00049 if (byte_order == DBUS_LITTLE_ENDIAN)
00050 return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
00051 else
00052 return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
00053 }
00054
00055 #ifndef DBUS_HAVE_INT64
00056
00057 static void
00058 swap_bytes (unsigned char *data,
00059 unsigned int len)
00060 {
00061 unsigned char *p1 = data;
00062 unsigned char *p2 = data + len - 1;
00063
00064 while (p1 < p2)
00065 {
00066 unsigned char tmp = *p1;
00067 *p1 = *p2;
00068 *p2 = tmp;
00069
00070 --p2;
00071 ++p1;
00072 }
00073 }
00074 #endif
00075
00080 typedef union
00081 {
00082 #ifdef DBUS_HAVE_INT64
00083 dbus_int64_t s;
00084 dbus_uint64_t u;
00085 #endif
00086 double d;
00087 } DBusOctets8;
00088
00089 static DBusOctets8
00090 unpack_8_octets (int byte_order,
00091 const unsigned char *data)
00092 {
00093 DBusOctets8 r;
00094
00095 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00096 _dbus_assert (sizeof (r) == 8);
00097
00098 #ifdef DBUS_HAVE_INT64
00099 if (byte_order == DBUS_LITTLE_ENDIAN)
00100 r.u = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
00101 else
00102 r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
00103 #else
00104 r.d = *(double*)data;
00105 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00106 swap_bytes ((unsigned char*) &r, sizeof (r));
00107 #endif
00108
00109 return r;
00110 }
00111
00119 dbus_uint32_t
00120 _dbus_unpack_uint32 (int byte_order,
00121 const unsigned char *data)
00122 {
00123 return unpack_4_octets (byte_order, data);
00124 }
00125
00133 dbus_int32_t
00134 _dbus_unpack_int32 (int byte_order,
00135 const unsigned char *data)
00136 {
00137 return (dbus_int32_t) unpack_4_octets (byte_order, data);
00138 }
00139
00140 #ifdef DBUS_HAVE_INT64
00141
00148 dbus_uint64_t
00149 _dbus_unpack_uint64 (int byte_order,
00150 const unsigned char *data)
00151 {
00152 DBusOctets8 r;
00153
00154 r = unpack_8_octets (byte_order, data);
00155
00156 return r.u;
00157 }
00158
00166 dbus_int64_t
00167 _dbus_unpack_int64 (int byte_order,
00168 const unsigned char *data)
00169 {
00170 DBusOctets8 r;
00171
00172 r = unpack_8_octets (byte_order, data);
00173
00174 return r.s;
00175 }
00176
00177 #endif
00178
00179 static void
00180 pack_4_octets (dbus_uint32_t value,
00181 int byte_order,
00182 unsigned char *data)
00183 {
00184 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
00185
00186 if ((byte_order) == DBUS_LITTLE_ENDIAN)
00187 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);
00188 else
00189 *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
00190 }
00191
00192 static void
00193 pack_8_octets (DBusOctets8 value,
00194 int byte_order,
00195 unsigned char *data)
00196 {
00197 _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
00198
00199 #ifdef DBUS_HAVE_INT64
00200 if ((byte_order) == DBUS_LITTLE_ENDIAN)
00201 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u);
00202 else
00203 *((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u);
00204 #else
00205 memcpy (data, &value, 8);
00206 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00207 swap_bytes ((unsigned char *)data, 8);
00208 #endif
00209 }
00210
00218 void
00219 _dbus_pack_uint32 (dbus_uint32_t value,
00220 int byte_order,
00221 unsigned char *data)
00222 {
00223 pack_4_octets (value, byte_order, data);
00224 }
00225
00233 void
00234 _dbus_pack_int32 (dbus_int32_t value,
00235 int byte_order,
00236 unsigned char *data)
00237 {
00238 pack_4_octets ((dbus_uint32_t) value, byte_order, data);
00239 }
00240
00241 #ifdef DBUS_HAVE_INT64
00242
00249 void
00250 _dbus_pack_uint64 (dbus_uint64_t value,
00251 int byte_order,
00252 unsigned char *data)
00253 {
00254 DBusOctets8 r;
00255 r.u = value;
00256 pack_8_octets (r, byte_order, data);
00257 }
00258
00266 void
00267 _dbus_pack_int64 (dbus_int64_t value,
00268 int byte_order,
00269 unsigned char *data)
00270 {
00271 DBusOctets8 r;
00272 r.s = value;
00273 pack_8_octets (r, byte_order, data);
00274 }
00275 #endif
00276
00277 static void
00278 set_4_octets (DBusString *str,
00279 int byte_order,
00280 int offset,
00281 dbus_uint32_t value)
00282 {
00283 char *data;
00284
00285 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00286 byte_order == DBUS_BIG_ENDIAN);
00287
00288 data = _dbus_string_get_data_len (str, offset, 4);
00289
00290 _dbus_pack_uint32 (value, byte_order, data);
00291 }
00292
00293 static void
00294 set_8_octets (DBusString *str,
00295 int byte_order,
00296 int offset,
00297 DBusOctets8 value)
00298 {
00299 char *data;
00300
00301 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00302 byte_order == DBUS_BIG_ENDIAN);
00303
00304 data = _dbus_string_get_data_len (str, offset, 8);
00305
00306 pack_8_octets (value, byte_order, data);
00307 }
00308
00319 void
00320 _dbus_marshal_set_int32 (DBusString *str,
00321 int byte_order,
00322 int offset,
00323 dbus_int32_t value)
00324 {
00325 set_4_octets (str, byte_order, offset, (dbus_uint32_t) value);
00326 }
00327
00338 void
00339 _dbus_marshal_set_uint32 (DBusString *str,
00340 int byte_order,
00341 int offset,
00342 dbus_uint32_t value)
00343 {
00344 set_4_octets (str, byte_order, offset, value);
00345 }
00346
00347 #ifdef DBUS_HAVE_INT64
00348
00359 void
00360 _dbus_marshal_set_int64 (DBusString *str,
00361 int byte_order,
00362 int offset,
00363 dbus_int64_t value)
00364 {
00365 DBusOctets8 r;
00366 r.s = value;
00367 set_8_octets (str, byte_order, offset, r);
00368 }
00369
00380 void
00381 _dbus_marshal_set_uint64 (DBusString *str,
00382 int byte_order,
00383 int offset,
00384 dbus_uint64_t value)
00385 {
00386 DBusOctets8 r;
00387 r.u = value;
00388 set_8_octets (str, byte_order, offset, r);
00389 }
00390 #endif
00391
00410 dbus_bool_t
00411 _dbus_marshal_set_string (DBusString *str,
00412 int byte_order,
00413 int offset,
00414 const DBusString *value,
00415 int len)
00416 {
00417 int old_len;
00418
00419 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
00420 byte_order == DBUS_BIG_ENDIAN);
00421
00422 old_len = _dbus_demarshal_uint32 (str, byte_order,
00423 offset, NULL);
00424
00425 if (!_dbus_string_replace_len (value, 0, len,
00426 str, offset + 4, old_len))
00427 return FALSE;
00428
00429 _dbus_marshal_set_uint32 (str, byte_order,
00430 offset, len);
00431
00432 return TRUE;
00433 }
00434
00448 void
00449 _dbus_marshal_set_object_path (DBusString *str,
00450 int byte_order,
00451 int offset,
00452 const char **path,
00453 int path_len)
00454 {
00455
00456
00457 }
00458
00459 static dbus_bool_t
00460 marshal_4_octets (DBusString *str,
00461 int byte_order,
00462 dbus_uint32_t value)
00463 {
00464 _dbus_assert (sizeof (value) == 4);
00465
00466 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00467 value = DBUS_UINT32_SWAP_LE_BE (value);
00468
00469 return _dbus_string_append_4_aligned (str,
00470 (const unsigned char *)&value);
00471 }
00472
00473 static dbus_bool_t
00474 marshal_8_octets (DBusString *str,
00475 int byte_order,
00476 DBusOctets8 value)
00477 {
00478 _dbus_assert (sizeof (value) == 8);
00479
00480 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00481 pack_8_octets (value, byte_order, (unsigned char*) &value);
00482
00483 return _dbus_string_append_8_aligned (str,
00484 (const unsigned char *)&value);
00485 }
00486
00495 dbus_bool_t
00496 _dbus_marshal_double (DBusString *str,
00497 int byte_order,
00498 double value)
00499 {
00500 DBusOctets8 r;
00501 r.d = value;
00502 return marshal_8_octets (str, byte_order, r);
00503 }
00504
00513 dbus_bool_t
00514 _dbus_marshal_int32 (DBusString *str,
00515 int byte_order,
00516 dbus_int32_t value)
00517 {
00518 return marshal_4_octets (str, byte_order, (dbus_uint32_t) value);
00519 }
00520
00529 dbus_bool_t
00530 _dbus_marshal_uint32 (DBusString *str,
00531 int byte_order,
00532 dbus_uint32_t value)
00533 {
00534 return marshal_4_octets (str, byte_order, value);
00535 }
00536
00537
00538 #ifdef DBUS_HAVE_INT64
00539
00547 dbus_bool_t
00548 _dbus_marshal_int64 (DBusString *str,
00549 int byte_order,
00550 dbus_int64_t value)
00551 {
00552 DBusOctets8 r;
00553 r.s = value;
00554 return marshal_8_octets (str, byte_order, r);
00555 }
00556
00565 dbus_bool_t
00566 _dbus_marshal_uint64 (DBusString *str,
00567 int byte_order,
00568 dbus_uint64_t value)
00569 {
00570 DBusOctets8 r;
00571 r.u = value;
00572 return marshal_8_octets (str, byte_order, r);
00573 }
00574
00575 #endif
00576
00588 dbus_bool_t
00589 _dbus_marshal_string (DBusString *str,
00590 int byte_order,
00591 const char *value)
00592 {
00593 int len, old_string_len;
00594
00595 old_string_len = _dbus_string_get_length (str);
00596
00597 len = strlen (value);
00598
00599 if (!_dbus_marshal_uint32 (str, byte_order, len))
00600 {
00601
00602 _dbus_string_set_length (str, old_string_len);
00603
00604 return FALSE;
00605 }
00606
00607 return _dbus_string_append_len (str, value, len + 1);
00608 }
00609
00622 dbus_bool_t
00623 _dbus_marshal_string_len (DBusString *str,
00624 int byte_order,
00625 const char *value,
00626 int len)
00627 {
00628 int old_string_len;
00629
00630 old_string_len = _dbus_string_get_length (str);
00631
00632 if (!_dbus_marshal_uint32 (str, byte_order, len))
00633 {
00634
00635 _dbus_string_set_length (str, old_string_len);
00636
00637 return FALSE;
00638 }
00639
00640 if (!_dbus_string_append_len (str, value, len))
00641 return FALSE;
00642
00643
00644 if (!_dbus_string_lengthen (str, 1))
00645 return FALSE;
00646
00647 return TRUE;
00648 }
00649
00659 dbus_bool_t
00660 _dbus_marshal_byte_array (DBusString *str,
00661 int byte_order,
00662 const unsigned char *value,
00663 int len)
00664 {
00665 int old_string_len;
00666
00667 old_string_len = _dbus_string_get_length (str);
00668
00669 if (!_dbus_marshal_uint32 (str, byte_order, len))
00670 {
00671
00672 _dbus_string_set_length (str, old_string_len);
00673
00674 return FALSE;
00675 }
00676
00677 if (len == 0)
00678 return TRUE;
00679 else
00680 return _dbus_string_append_len (str, value, len);
00681 }
00682
00683 static dbus_bool_t
00684 marshal_4_octets_array (DBusString *str,
00685 int byte_order,
00686 const dbus_uint32_t *value,
00687 int len)
00688 {
00689 int old_string_len;
00690 int array_start;
00691
00692 old_string_len = _dbus_string_get_length (str);
00693
00694 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
00695 goto error;
00696
00697 array_start = _dbus_string_get_length (str);
00698
00699 if (!_dbus_string_append_len (str, (const unsigned char*) value,
00700 len * 4))
00701 goto error;
00702
00703 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00704 {
00705 const unsigned char *d;
00706 const unsigned char *end;
00707
00708 d = _dbus_string_get_data (str) + array_start;
00709 end = d + len * 4;
00710 while (d != end)
00711 {
00712 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
00713 d += 4;
00714 }
00715 }
00716
00717 return TRUE;
00718
00719 error:
00720
00721 _dbus_string_set_length (str, old_string_len);
00722
00723 return FALSE;
00724 }
00725
00726 static dbus_bool_t
00727 marshal_8_octets_array (DBusString *str,
00728 int byte_order,
00729 const DBusOctets8 *value,
00730 int len)
00731 {
00732 int old_string_len;
00733 int array_start;
00734
00735 old_string_len = _dbus_string_get_length (str);
00736
00737 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
00738 goto error;
00739
00740 array_start = _dbus_string_get_length (str);
00741
00742 if (!_dbus_string_append_len (str, (const unsigned char*) value,
00743 len * 8))
00744 goto error;
00745
00746 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00747 {
00748 const unsigned char *d;
00749 const unsigned char *end;
00750
00751 d = _dbus_string_get_data (str) + array_start;
00752 end = d + len * 8;
00753 while (d != end)
00754 {
00755 #ifdef DBUS_HAVE_INT64
00756 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
00757 #else
00758 swap_bytes ((unsigned char*) d, 8);
00759 #endif
00760 d += 8;
00761 }
00762 }
00763
00764 return TRUE;
00765
00766 error:
00767
00768 _dbus_string_set_length (str, old_string_len);
00769
00770 return FALSE;
00771 }
00772
00782 dbus_bool_t
00783 _dbus_marshal_int32_array (DBusString *str,
00784 int byte_order,
00785 const dbus_int32_t *value,
00786 int len)
00787 {
00788 return marshal_4_octets_array (str, byte_order,
00789 (const dbus_uint32_t*) value,
00790 len);
00791 }
00792
00802 dbus_bool_t
00803 _dbus_marshal_uint32_array (DBusString *str,
00804 int byte_order,
00805 const dbus_uint32_t *value,
00806 int len)
00807 {
00808 return marshal_4_octets_array (str, byte_order,
00809 value,
00810 len);
00811 }
00812
00813 #ifdef DBUS_HAVE_INT64
00814
00824 dbus_bool_t
00825 _dbus_marshal_int64_array (DBusString *str,
00826 int byte_order,
00827 const dbus_int64_t *value,
00828 int len)
00829 {
00830 return marshal_8_octets_array (str, byte_order,
00831 (const DBusOctets8*) value,
00832 len);
00833 }
00834
00844 dbus_bool_t
00845 _dbus_marshal_uint64_array (DBusString *str,
00846 int byte_order,
00847 const dbus_uint64_t *value,
00848 int len)
00849 {
00850 return marshal_8_octets_array (str, byte_order,
00851 (const DBusOctets8*) value,
00852 len);
00853 }
00854
00855 #endif
00856
00866 dbus_bool_t
00867 _dbus_marshal_double_array (DBusString *str,
00868 int byte_order,
00869 const double *value,
00870 int len)
00871 {
00872 return marshal_8_octets_array (str, byte_order,
00873 (const DBusOctets8*) value,
00874 len);
00875 }
00876
00886 dbus_bool_t
00887 _dbus_marshal_string_array (DBusString *str,
00888 int byte_order,
00889 const char **value,
00890 int len)
00891 {
00892 int i, old_string_len, array_start;
00893
00894 old_string_len = _dbus_string_get_length (str);
00895
00896
00897 if (!_dbus_marshal_uint32 (str, byte_order, 0))
00898 goto error;
00899
00900 array_start = _dbus_string_get_length (str);
00901
00902 for (i = 0; i < len; i++)
00903 if (!_dbus_marshal_string (str, byte_order, value[i]))
00904 goto error;
00905
00906
00907 _dbus_marshal_set_uint32 (str, byte_order,
00908 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00909 _dbus_string_get_length (str) - array_start);
00910
00911 return TRUE;
00912
00913 error:
00914
00915 _dbus_string_set_length (str, old_string_len);
00916
00917 return FALSE;
00918 }
00919
00929 dbus_bool_t
00930 _dbus_marshal_object_path (DBusString *str,
00931 int byte_order,
00932 const char **path,
00933 int path_len)
00934 {
00935 int array_start, old_string_len;
00936 int i;
00937
00938 old_string_len = _dbus_string_get_length (str);
00939
00940
00941 if (!_dbus_marshal_uint32 (str, byte_order, 0))
00942 goto nomem;
00943
00944 array_start = _dbus_string_get_length (str);
00945
00946 i = 0;
00947 while (i < path_len)
00948 {
00949 if (!_dbus_string_append_byte (str, '/'))
00950 goto nomem;
00951
00952 if (!_dbus_string_append (str, path[0]))
00953 goto nomem;
00954
00955 ++i;
00956 }
00957
00958
00959 _dbus_marshal_set_uint32 (str, byte_order,
00960 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00961 _dbus_string_get_length (str) - array_start);
00962
00963 return TRUE;
00964
00965 nomem:
00966
00967 _dbus_string_set_length (str, old_string_len);
00968
00969 return FALSE;
00970 }
00971
00972 static dbus_uint32_t
00973 demarshal_4_octets (const DBusString *str,
00974 int byte_order,
00975 int pos,
00976 int *new_pos)
00977 {
00978 const DBusRealString *real = (const DBusRealString*) str;
00979
00980 pos = _DBUS_ALIGN_VALUE (pos, 4);
00981
00982 if (new_pos)
00983 *new_pos = pos + 4;
00984
00985 return unpack_4_octets (byte_order, real->str + pos);
00986 }
00987
00988 static DBusOctets8
00989 demarshal_8_octets (const DBusString *str,
00990 int byte_order,
00991 int pos,
00992 int *new_pos)
00993 {
00994 const DBusRealString *real = (const DBusRealString*) str;
00995
00996 pos = _DBUS_ALIGN_VALUE (pos, 8);
00997
00998 if (new_pos)
00999 *new_pos = pos + 8;
01000
01001 return unpack_8_octets (byte_order, real->str + pos);
01002 }
01003
01013 double
01014 _dbus_demarshal_double (const DBusString *str,
01015 int byte_order,
01016 int pos,
01017 int *new_pos)
01018 {
01019 DBusOctets8 r;
01020
01021 r = demarshal_8_octets (str, byte_order, pos, new_pos);
01022
01023 return r.d;
01024 }
01025
01035 dbus_int32_t
01036 _dbus_demarshal_int32 (const DBusString *str,
01037 int byte_order,
01038 int pos,
01039 int *new_pos)
01040 {
01041 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
01042 }
01043
01053 dbus_uint32_t
01054 _dbus_demarshal_uint32 (const DBusString *str,
01055 int byte_order,
01056 int pos,
01057 int *new_pos)
01058 {
01059 return demarshal_4_octets (str, byte_order, pos, new_pos);
01060 }
01061
01062 #ifdef DBUS_HAVE_INT64
01063
01073 dbus_int64_t
01074 _dbus_demarshal_int64 (const DBusString *str,
01075 int byte_order,
01076 int pos,
01077 int *new_pos)
01078 {
01079 DBusOctets8 r;
01080
01081 r = demarshal_8_octets (str, byte_order, pos, new_pos);
01082
01083 return r.s;
01084 }
01085
01095 dbus_uint64_t
01096 _dbus_demarshal_uint64 (const DBusString *str,
01097 int byte_order,
01098 int pos,
01099 int *new_pos)
01100 {
01101 DBusOctets8 r;
01102
01103 r = demarshal_8_octets (str, byte_order, pos, new_pos);
01104
01105 return r.u;
01106 }
01107
01108 #endif
01109
01120 void
01121 _dbus_demarshal_basic_type (const DBusString *str,
01122 int type,
01123 void *value,
01124 int byte_order,
01125 int *pos)
01126 {
01127 const char *str_data = _dbus_string_get_const_data (str);
01128
01129 switch (type)
01130 {
01131 case DBUS_TYPE_BYTE:
01132 case DBUS_TYPE_BOOLEAN:
01133 *(unsigned char *) value = _dbus_string_get_byte (str, *pos);
01134 (*pos)++;
01135 break;
01136 case DBUS_TYPE_INT32:
01137 case DBUS_TYPE_UINT32:
01138 *pos = _DBUS_ALIGN_VALUE (*pos, 4);
01139 *(dbus_uint32_t *) value = *(dbus_uint32_t *)(str_data + *pos);
01140 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01141 *(dbus_uint32_t *) value = DBUS_UINT32_SWAP_LE_BE (*(dbus_uint32_t *) value);
01142 *pos += 4;
01143 break;
01144 #ifdef DBUS_HAVE_INT64
01145 case DBUS_TYPE_INT64:
01146 case DBUS_TYPE_UINT64:
01147 #endif
01148 case DBUS_TYPE_DOUBLE:
01149 *pos = _DBUS_ALIGN_VALUE (*pos, 8);
01150 memcpy (value, str_data + *pos, 8);
01151 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01152 #ifdef DBUS_HAVE_INT64
01153 *(dbus_uint64_t *) value = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t *) value);
01154 #else
01155 swap_bytes (value, 8);
01156 #endif
01157 *pos += 8;
01158 break;
01159 default:
01160 _dbus_assert_not_reached ("not a basic type");
01161 break;
01162 }
01163 }
01164
01181 char *
01182 _dbus_demarshal_string (const DBusString *str,
01183 int byte_order,
01184 int pos,
01185 int *new_pos)
01186 {
01187 int len;
01188 char *retval;
01189 const char *data;
01190
01191 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01192
01193 retval = dbus_malloc (len + 1);
01194
01195 if (!retval)
01196 return NULL;
01197
01198 data = _dbus_string_get_const_data_len (str, pos, len + 1);
01199
01200 if (!data)
01201 return NULL;
01202
01203 memcpy (retval, data, len + 1);
01204
01205 if (new_pos)
01206 *new_pos = pos + len + 1;
01207
01208 return retval;
01209 }
01210
01226 dbus_bool_t
01227 _dbus_demarshal_byte_array (const DBusString *str,
01228 int byte_order,
01229 int pos,
01230 int *new_pos,
01231 unsigned char **array,
01232 int *array_len)
01233 {
01234 int len;
01235 unsigned char *retval;
01236 const char *data;
01237
01238 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01239
01240 if (len == 0)
01241 {
01242 *array_len = len;
01243 *array = NULL;
01244
01245 if (new_pos)
01246 *new_pos = pos;
01247
01248 return TRUE;
01249 }
01250
01251 retval = dbus_malloc (len);
01252
01253 if (!retval)
01254 return FALSE;
01255
01256 data = _dbus_string_get_const_data_len (str, pos, len);
01257
01258 if (!data)
01259 {
01260 dbus_free (retval);
01261 return FALSE;
01262 }
01263
01264 memcpy (retval, data, len);
01265
01266 if (new_pos)
01267 *new_pos = pos + len;
01268
01269 *array = retval;
01270 *array_len = len;
01271
01272 return TRUE;
01273 }
01274
01275 static dbus_bool_t
01276 demarshal_4_octets_array (const DBusString *str,
01277 int byte_order,
01278 int pos,
01279 int *new_pos,
01280 dbus_uint32_t **array,
01281 int *array_len)
01282 {
01283 int len, i;
01284 dbus_uint32_t *retval;
01285 int byte_len;
01286
01287 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01288 len = byte_len / 4;
01289
01290 if (len == 0)
01291 {
01292 *array_len = 0;
01293 *array = NULL;
01294
01295 if (new_pos)
01296 *new_pos = pos;
01297
01298 return TRUE;
01299 }
01300
01301 if (!_dbus_string_copy_data_len (str, (char**) &retval,
01302 pos, byte_len))
01303 return FALSE;
01304
01305 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01306 {
01307 for (i = 0; i < len; i++)
01308 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
01309 }
01310
01311 if (new_pos)
01312 *new_pos = pos + byte_len;
01313
01314 *array_len = len;
01315 *array = retval;
01316
01317 return TRUE;
01318 }
01319
01320 static dbus_bool_t
01321 demarshal_8_octets_array (const DBusString *str,
01322 int byte_order,
01323 int pos,
01324 int *new_pos,
01325 DBusOctets8 **array,
01326 int *array_len)
01327 {
01328 int len, i;
01329 DBusOctets8 *retval;
01330 int byte_len;
01331
01332 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01333 len = byte_len / 8;
01334
01335 if (len == 0)
01336 {
01337 *array_len = 0;
01338 *array = NULL;
01339
01340 if (new_pos)
01341 *new_pos = pos;
01342
01343 return TRUE;
01344 }
01345
01346 if (!_dbus_string_copy_data_len (str, (char**) &retval,
01347 pos, byte_len))
01348 return FALSE;
01349
01350 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01351 {
01352 for (i = 0; i < len; i++)
01353 {
01354 #ifdef DBUS_HAVE_INT64
01355 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
01356 #else
01357 swap_bytes ((unsigned char *) &retval[i], 8);
01358 #endif
01359 }
01360 }
01361
01362 if (new_pos)
01363 *new_pos = pos + byte_len;
01364
01365 *array_len = len;
01366 *array = retval;
01367
01368 return TRUE;
01369 }
01370
01382 dbus_bool_t
01383 _dbus_demarshal_int32_array (const DBusString *str,
01384 int byte_order,
01385 int pos,
01386 int *new_pos,
01387 dbus_int32_t **array,
01388 int *array_len)
01389 {
01390 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01391 (dbus_uint32_t**) array, array_len);
01392 }
01393
01405 dbus_bool_t
01406 _dbus_demarshal_uint32_array (const DBusString *str,
01407 int byte_order,
01408 int pos,
01409 int *new_pos,
01410 dbus_uint32_t **array,
01411 int *array_len)
01412 {
01413 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01414 array, array_len);
01415 }
01416
01417 #ifdef DBUS_HAVE_INT64
01418
01430 dbus_bool_t
01431 _dbus_demarshal_int64_array (const DBusString *str,
01432 int byte_order,
01433 int pos,
01434 int *new_pos,
01435 dbus_int64_t **array,
01436 int *array_len)
01437 {
01438 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01439 (DBusOctets8**) array, array_len);
01440 }
01441
01453 dbus_bool_t
01454 _dbus_demarshal_uint64_array (const DBusString *str,
01455 int byte_order,
01456 int pos,
01457 int *new_pos,
01458 dbus_uint64_t **array,
01459 int *array_len)
01460 {
01461 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01462 (DBusOctets8**) array, array_len);
01463 }
01464
01465 #endif
01466
01478 dbus_bool_t
01479 _dbus_demarshal_double_array (const DBusString *str,
01480 int byte_order,
01481 int pos,
01482 int *new_pos,
01483 double **array,
01484 int *array_len)
01485 {
01486 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01487 (DBusOctets8**) array, array_len);
01488 }
01489
01490
01502 dbus_bool_t
01503 _dbus_demarshal_basic_type_array (const DBusString *str,
01504 int element_type,
01505 void **array,
01506 int *array_len,
01507 int byte_order,
01508 int *pos)
01509 {
01510 switch (element_type)
01511 {
01512 case DBUS_TYPE_BOOLEAN:
01513
01514 case DBUS_TYPE_BYTE:
01515 return _dbus_demarshal_byte_array (str, byte_order, *pos, pos,
01516 (unsigned char **)array, array_len);
01517 break;
01518 case DBUS_TYPE_INT32:
01519 case DBUS_TYPE_UINT32:
01520 return demarshal_4_octets_array (str, byte_order, *pos, pos,
01521 (dbus_uint32_t **)array, array_len);
01522 break;
01523 #ifdef DBUS_HAVE_INT64
01524 case DBUS_TYPE_INT64:
01525 case DBUS_TYPE_UINT64:
01526 #endif
01527 case DBUS_TYPE_DOUBLE:
01528 return demarshal_8_octets_array (str, byte_order, *pos, pos,
01529 (DBusOctets8**) array, array_len);
01530 default:
01531 _dbus_assert_not_reached ("not a basic type");
01532 break;
01533 }
01534 return FALSE;
01535 }
01536
01548 dbus_bool_t
01549 _dbus_demarshal_string_array (const DBusString *str,
01550 int byte_order,
01551 int pos,
01552 int *new_pos,
01553 char ***array,
01554 int *array_len)
01555 {
01556 int bytes_len, i;
01557 int len, allocated;
01558 int end_pos;
01559 char **retval;
01560
01561 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01562
01563 if (bytes_len == 0)
01564 {
01565 *array_len = 0;
01566 *array = NULL;
01567
01568 if (new_pos)
01569 *new_pos = pos;
01570
01571 return TRUE;
01572 }
01573
01574 len = 0;
01575 allocated = 4;
01576 end_pos = pos + bytes_len;
01577
01578 retval = dbus_new (char *, allocated);
01579
01580 if (!retval)
01581 return FALSE;
01582
01583 while (pos < end_pos)
01584 {
01585 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
01586
01587 if (retval[len] == NULL)
01588 goto error;
01589
01590 len += 1;
01591
01592 if (len >= allocated - 1)
01593 {
01594 char **newp;
01595 newp = dbus_realloc (retval,
01596 sizeof (char*) * allocated * 2);
01597 if (newp == NULL)
01598 goto error;
01599
01600 allocated *= 2;
01601 retval = newp;
01602 }
01603 }
01604
01605 retval[len] = NULL;
01606
01607 if (new_pos)
01608 *new_pos = pos;
01609
01610 *array = retval;
01611 *array_len = len;
01612
01613 return TRUE;
01614
01615 error:
01616 for (i = 0; i < len; i++)
01617 dbus_free (retval[i]);
01618 dbus_free (retval);
01619
01620 return FALSE;
01621 }
01622
01624 #define VERBOSE_DECOMPOSE 0
01625
01635 dbus_bool_t
01636 _dbus_decompose_path (const char* data,
01637 int len,
01638 char ***path,
01639 int *path_len)
01640 {
01641 char **retval;
01642 int n_components;
01643 int i, j, comp;
01644
01645 _dbus_assert (data != NULL);
01646
01647 #if VERBOSE_DECOMPOSE
01648 _dbus_verbose ("Decomposing path \"%s\"\n",
01649 data);
01650 #endif
01651
01652 n_components = 0;
01653 i = 0;
01654 while (i < len)
01655 {
01656 if (data[i] == '/')
01657 n_components += 1;
01658 ++i;
01659 }
01660
01661 retval = dbus_new0 (char*, n_components + 1);
01662
01663 if (retval == NULL)
01664 return FALSE;
01665
01666 comp = 0;
01667 i = 0;
01668 while (i < len)
01669 {
01670 if (data[i] == '/')
01671 ++i;
01672 j = i;
01673
01674 while (j < len && data[j] != '/')
01675 ++j;
01676
01677
01678 _dbus_assert (i < j);
01679 _dbus_assert (data[i] != '/');
01680 _dbus_assert (j == len || data[j] == '/');
01681
01682 #if VERBOSE_DECOMPOSE
01683 _dbus_verbose (" (component in [%d,%d))\n",
01684 i, j);
01685 #endif
01686
01687 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
01688 if (retval[comp] == NULL)
01689 {
01690 dbus_free_string_array (retval);
01691 return FALSE;
01692 }
01693 retval[comp][j-i] = '\0';
01694 #if VERBOSE_DECOMPOSE
01695 _dbus_verbose (" (component %d = \"%s\")\n",
01696 comp, retval[comp]);
01697 #endif
01698
01699 ++comp;
01700 i = j;
01701 }
01702 _dbus_assert (i == len);
01703
01704 *path = retval;
01705 if (path_len)
01706 *path_len = n_components;
01707
01708 return TRUE;
01709 }
01710
01722 dbus_bool_t
01723 _dbus_demarshal_object_path (const DBusString *str,
01724 int byte_order,
01725 int pos,
01726 int *new_pos,
01727 char ***path,
01728 int *path_len)
01729 {
01730 int len;
01731 const char *data;
01732
01733 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01734 data = _dbus_string_get_const_data_len (str, pos, len + 1);
01735
01736 if (!_dbus_decompose_path (data, len, path, path_len))
01737 return FALSE;
01738
01739 if (new_pos)
01740 *new_pos = pos + len + 1;
01741
01742 return TRUE;
01743 }
01744
01758 dbus_bool_t
01759 _dbus_marshal_get_arg_end_pos (const DBusString *str,
01760 int byte_order,
01761 int type,
01762 int pos,
01763 int *end_pos)
01764 {
01765 if (pos >= _dbus_string_get_length (str))
01766 return FALSE;
01767
01768 switch (type)
01769 {
01770 case DBUS_TYPE_INVALID:
01771 return FALSE;
01772 break;
01773
01774 case DBUS_TYPE_NIL:
01775 *end_pos = pos;
01776 break;
01777
01778 case DBUS_TYPE_BYTE:
01779 *end_pos = pos + 1;
01780 break;
01781
01782 case DBUS_TYPE_BOOLEAN:
01783 *end_pos = pos + 1;
01784 break;
01785
01786 case DBUS_TYPE_INT32:
01787 case DBUS_TYPE_UINT32:
01788 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
01789 break;
01790
01791 case DBUS_TYPE_INT64:
01792 case DBUS_TYPE_UINT64:
01793 case DBUS_TYPE_DOUBLE:
01794
01795 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
01796 break;
01797
01798 case DBUS_TYPE_OBJECT_PATH:
01799 case DBUS_TYPE_STRING:
01800 {
01801 int len;
01802
01803
01804 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01805
01806 *end_pos = pos + len + 1;
01807 }
01808 break;
01809
01810 case DBUS_TYPE_CUSTOM:
01811 {
01812 int len;
01813
01814
01815 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01816
01817 pos += len + 1;
01818
01819
01820 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01821
01822 *end_pos = pos + len;
01823 }
01824 break;
01825
01826 case DBUS_TYPE_ARRAY:
01827 {
01828 int len;
01829
01830
01831 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01832
01833 *end_pos = pos + len;
01834 }
01835 break;
01836
01837 case DBUS_TYPE_DICT:
01838 {
01839 int len;
01840
01841
01842 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01843
01844 *end_pos = pos + len;
01845 }
01846 break;
01847
01848 default:
01849 _dbus_warn ("Unknown message arg type %d\n", type);
01850 _dbus_assert_not_reached ("Unknown message argument type\n");
01851 return FALSE;
01852 }
01853
01854 if (*end_pos > _dbus_string_get_length (str))
01855 return FALSE;
01856
01857 return TRUE;
01858 }
01859
01873 static int
01874 demarshal_and_validate_len (const DBusString *str,
01875 int byte_order,
01876 int pos,
01877 int *new_pos)
01878 {
01879 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
01880 unsigned int len;
01881
01882 _dbus_assert (new_pos != NULL);
01883
01884 if ((align_4 + 4) > _dbus_string_get_length (str))
01885 {
01886 _dbus_verbose ("not enough room in message for array length\n");
01887 return -1;
01888 }
01889
01890 if (!_dbus_string_validate_nul (str, pos,
01891 align_4 - pos))
01892 {
01893 _dbus_verbose ("array length alignment padding not initialized to nul at %d\n", pos);
01894 return -1;
01895 }
01896
01897 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
01898
01899
01900
01901
01902
01903
01904
01905 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
01906 if (len > MAX_ARRAY_LENGTH)
01907 {
01908 _dbus_verbose ("array length %u exceeds maximum of %u at pos %d\n",
01909 len, MAX_ARRAY_LENGTH, pos);
01910 return -1;
01911 }
01912 else
01913 return (int) len;
01914 }
01915
01916 static dbus_bool_t
01917 validate_string (const DBusString *str,
01918 int pos,
01919 int len_without_nul,
01920 int *end_pos)
01921 {
01922 *end_pos = pos + len_without_nul + 1;
01923
01924 if (*end_pos > _dbus_string_get_length (str))
01925 {
01926 _dbus_verbose ("string length outside length of the message\n");
01927 return FALSE;
01928 }
01929
01930 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
01931 {
01932 _dbus_verbose ("string arg not nul-terminated\n");
01933 return FALSE;
01934 }
01935
01936 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
01937 {
01938 _dbus_verbose ("string is not valid UTF-8\n");
01939 return FALSE;
01940 }
01941
01942 return TRUE;
01943 }
01944
01956 dbus_bool_t
01957 _dbus_marshal_validate_type (const DBusString *str,
01958 int pos,
01959 int *type,
01960 int *end_pos)
01961 {
01962 const char *data;
01963
01964 if (pos >= _dbus_string_get_length (str))
01965 return FALSE;
01966
01967 data = _dbus_string_get_const_data_len (str, pos, 1);
01968
01969 if (_dbus_type_is_valid (*data))
01970 {
01971 *type = *data;
01972 if (end_pos != NULL)
01973 *end_pos = pos + 1;
01974 return TRUE;
01975 }
01976
01977 _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
01978
01979 return FALSE;
01980 }
01981
01982
01983
01984
01985 static dbus_bool_t
01986 validate_array_data (const DBusString *str,
01987 int byte_order,
01988 int depth,
01989 int type,
01990 int array_type_pos,
01991 int pos,
01992 int *new_pos,
01993 int end)
01994 {
01995 switch (type)
01996 {
01997 case DBUS_TYPE_INVALID:
01998 return FALSE;
01999 break;
02000
02001 case DBUS_TYPE_NIL:
02002 break;
02003
02004 case DBUS_TYPE_OBJECT_PATH:
02005 case DBUS_TYPE_STRING:
02006 case DBUS_TYPE_CUSTOM:
02007 case DBUS_TYPE_ARRAY:
02008 case DBUS_TYPE_DICT:
02009
02010
02011
02012
02013
02014
02015 while (pos < end)
02016 {
02017 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
02018 type, array_type_pos, pos, &pos))
02019 return FALSE;
02020 }
02021 break;
02022
02023 case DBUS_TYPE_BYTE:
02024 pos = end;
02025 break;
02026
02027 case DBUS_TYPE_BOOLEAN:
02028 while (pos < end)
02029 {
02030 unsigned char c;
02031
02032 c = _dbus_string_get_byte (str, pos);
02033
02034 if (!(c == 0 || c == 1))
02035 {
02036 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
02037 return FALSE;
02038 }
02039
02040 ++pos;
02041 }
02042 break;
02043
02044 case DBUS_TYPE_INT32:
02045 case DBUS_TYPE_UINT32:
02046
02047
02048
02049 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
02050 type, array_type_pos, pos, &pos))
02051 return FALSE;
02052 pos = _DBUS_ALIGN_VALUE (end, 4);
02053 break;
02054
02055 case DBUS_TYPE_INT64:
02056 case DBUS_TYPE_UINT64:
02057 case DBUS_TYPE_DOUBLE:
02058
02059
02060
02061 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
02062 type, array_type_pos, pos, &pos))
02063 return FALSE;
02064 pos = _DBUS_ALIGN_VALUE (end, 8);
02065 break;
02066
02067 default:
02068 _dbus_verbose ("Unknown message arg type %d\n", type);
02069 return FALSE;
02070 }
02071
02072 *new_pos = pos;
02073
02074 return TRUE;
02075 }
02076
02097 dbus_bool_t
02098 _dbus_marshal_validate_arg (const DBusString *str,
02099 int byte_order,
02100 int depth,
02101 int type,
02102 int array_type_pos,
02103 int pos,
02104 int *end_pos)
02105 {
02106 if (pos > _dbus_string_get_length (str))
02107 {
02108 _dbus_verbose ("Validation went off the end of the message\n");
02109 return FALSE;
02110 }
02111
02112 #define MAX_VALIDATION_DEPTH 32
02113
02114 if (depth > MAX_VALIDATION_DEPTH)
02115 {
02116 _dbus_verbose ("Maximum recursion depth reached validating message\n");
02117 return FALSE;
02118 }
02119
02120 switch (type)
02121 {
02122 case DBUS_TYPE_INVALID:
02123 return FALSE;
02124 break;
02125
02126 case DBUS_TYPE_NIL:
02127 *end_pos = pos;
02128 break;
02129
02130 case DBUS_TYPE_BYTE:
02131 if (1 > _dbus_string_get_length (str) - pos)
02132 {
02133 _dbus_verbose ("no room for byte value\n");
02134 return FALSE;
02135 }
02136
02137 *end_pos = pos + 1;
02138 break;
02139
02140 case DBUS_TYPE_BOOLEAN:
02141 {
02142 unsigned char c;
02143
02144 if (1 > _dbus_string_get_length (str) - pos)
02145 {
02146 _dbus_verbose ("no room for boolean value\n");
02147 return FALSE;
02148 }
02149
02150 c = _dbus_string_get_byte (str, pos);
02151
02152 if (!(c == 0 || c == 1))
02153 {
02154 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
02155 return FALSE;
02156 }
02157
02158 *end_pos = pos + 1;
02159 }
02160 break;
02161
02162 case DBUS_TYPE_INT32:
02163 case DBUS_TYPE_UINT32:
02164 {
02165 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
02166
02167 if (!_dbus_string_validate_nul (str, pos,
02168 align_4 - pos))
02169 {
02170 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
02171 return FALSE;
02172 }
02173
02174 *end_pos = align_4 + 4;
02175 }
02176 break;
02177
02178 case DBUS_TYPE_INT64:
02179 case DBUS_TYPE_UINT64:
02180 case DBUS_TYPE_DOUBLE:
02181 {
02182 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
02183
02184 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
02185
02186 if (!_dbus_string_validate_nul (str, pos,
02187 align_8 - pos))
02188 {
02189 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul at %d\n", pos);
02190 return FALSE;
02191 }
02192
02193 *end_pos = align_8 + 8;
02194 }
02195 break;
02196
02197 case DBUS_TYPE_OBJECT_PATH:
02198 case DBUS_TYPE_STRING:
02199 {
02200 int len;
02201
02202
02203
02204
02205 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02206 if (len < 0)
02207 return FALSE;
02208
02209 if (!validate_string (str, pos, len, end_pos))
02210 return FALSE;
02211
02212 if (type == DBUS_TYPE_OBJECT_PATH)
02213 {
02214 if (!_dbus_string_validate_path (str, pos, len))
02215 return FALSE;
02216 }
02217 }
02218 break;
02219
02220 case DBUS_TYPE_CUSTOM:
02221 {
02222 int len;
02223
02224
02225
02226
02227 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02228 if (len < 0)
02229 return FALSE;
02230
02231 if (!validate_string (str, pos, len, &pos))
02232 return FALSE;
02233
02234
02235 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02236 if (len < 0)
02237 return FALSE;
02238
02239 *end_pos = pos + len;
02240 }
02241 break;
02242
02243 case DBUS_TYPE_ARRAY:
02244 {
02245 int len;
02246 int end;
02247 int array_type;
02248
02249 if (array_type_pos == -1)
02250 {
02251 array_type_pos = pos;
02252
02253 do
02254 {
02255 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
02256 {
02257 _dbus_verbose ("invalid array type\n");
02258 return FALSE;
02259 }
02260
02261
02262
02263
02264
02265 if (array_type == DBUS_TYPE_NIL)
02266 {
02267 _dbus_verbose ("array of NIL is not allowed\n");
02268 return FALSE;
02269 }
02270 }
02271 while (array_type == DBUS_TYPE_ARRAY);
02272 }
02273 else
02274 array_type_pos++;
02275
02276 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
02277 {
02278 _dbus_verbose ("invalid array type\n");
02279 return FALSE;
02280 }
02281
02282 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02283 if (len < 0)
02284 {
02285 _dbus_verbose ("invalid array length (<0)\n");
02286 return FALSE;
02287 }
02288
02289 if (len > _dbus_string_get_length (str) - pos)
02290 {
02291 _dbus_verbose ("array length outside length of the message\n");
02292 return FALSE;
02293 }
02294
02295 end = pos + len;
02296
02297 if (len > 0 && !validate_array_data (str, byte_order, depth + 1,
02298 array_type, array_type_pos,
02299 pos, &pos, end))
02300 {
02301 _dbus_verbose ("invalid array data\n");
02302 return FALSE;
02303 }
02304
02305 if (pos < end)
02306 {
02307
02308
02309
02310 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
02311 len, end - pos);
02312 return FALSE;
02313 }
02314
02315 if (pos > end)
02316 {
02317 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
02318 return FALSE;
02319 }
02320
02321 *end_pos = pos;
02322 }
02323 break;
02324
02325 case DBUS_TYPE_DICT:
02326 {
02327 int dict_type;
02328 int len;
02329 int end;
02330
02331 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02332 if (len < 0)
02333 return FALSE;
02334
02335 if (len > _dbus_string_get_length (str) - pos)
02336 {
02337 _dbus_verbose ("dict length outside length of the message\n");
02338 return FALSE;
02339 }
02340
02341 end = pos + len;
02342
02343 while (pos < end)
02344 {
02345
02346 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02347 DBUS_TYPE_STRING, -1, pos, &pos))
02348 return FALSE;
02349
02350 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
02351 {
02352 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
02353 return FALSE;
02354 }
02355
02356
02357 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02358 dict_type, -1, pos, &pos))
02359 {
02360 _dbus_verbose ("dict arg invalid at offset %d\n", pos);
02361 return FALSE;
02362 }
02363 }
02364
02365 if (pos > end)
02366 {
02367 _dbus_verbose ("dict contents exceed stated dict length\n");
02368 return FALSE;
02369 }
02370
02371 *end_pos = pos;
02372 }
02373 break;
02374
02375 default:
02376 _dbus_verbose ("Unknown message arg type %d\n", type);
02377 return FALSE;
02378 }
02379
02380 if (*end_pos > _dbus_string_get_length (str))
02381 return FALSE;
02382
02383 return TRUE;
02384 }
02385
02391 dbus_bool_t
02392 _dbus_type_is_valid (int typecode)
02393 {
02394 switch (typecode)
02395 {
02396 case DBUS_TYPE_NIL:
02397 case DBUS_TYPE_BYTE:
02398 case DBUS_TYPE_BOOLEAN:
02399 case DBUS_TYPE_INT32:
02400 case DBUS_TYPE_UINT32:
02401 case DBUS_TYPE_INT64:
02402 case DBUS_TYPE_UINT64:
02403 case DBUS_TYPE_DOUBLE:
02404 case DBUS_TYPE_STRING:
02405 case DBUS_TYPE_CUSTOM:
02406 case DBUS_TYPE_ARRAY:
02407 case DBUS_TYPE_DICT:
02408 case DBUS_TYPE_OBJECT_PATH:
02409 return TRUE;
02410
02411 default:
02412 return FALSE;
02413 }
02414 }
02415
02424 void
02425 _dbus_verbose_bytes (const unsigned char *data,
02426 int len)
02427 {
02428 int i;
02429 const unsigned char *aligned;
02430
02431 _dbus_assert (len >= 0);
02432
02433
02434 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
02435 if (aligned > data)
02436 aligned -= 4;
02437 _dbus_assert (aligned <= data);
02438
02439 if (aligned != data)
02440 {
02441 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
02442 while (aligned != data)
02443 {
02444 _dbus_verbose (" ");
02445 ++aligned;
02446 }
02447 }
02448
02449
02450 i = 0;
02451 while (i < len)
02452 {
02453 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02454 {
02455 _dbus_verbose ("%4d\t%p: ",
02456 i, &data[i]);
02457 }
02458
02459 if (data[i] >= 32 &&
02460 data[i] <= 126)
02461 _dbus_verbose (" '%c' ", data[i]);
02462 else
02463 _dbus_verbose ("0x%s%x ",
02464 data[i] <= 0xf ? "0" : "", data[i]);
02465
02466 ++i;
02467
02468 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02469 {
02470 if (i > 3)
02471 _dbus_verbose ("BE: %d LE: %d",
02472 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
02473 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
02474
02475 if (i > 7 &&
02476 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
02477 {
02478 _dbus_verbose (" dbl: %g",
02479 *(double*)&data[i-8]);
02480 }
02481
02482 _dbus_verbose ("\n");
02483 }
02484 }
02485
02486 _dbus_verbose ("\n");
02487 }
02488
02496 void
02497 _dbus_verbose_bytes_of_string (const DBusString *str,
02498 int start,
02499 int len)
02500 {
02501 const char *d;
02502 int real_len;
02503
02504 real_len = _dbus_string_get_length (str);
02505
02506 _dbus_assert (start >= 0);
02507
02508 if (start > real_len)
02509 {
02510 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
02511 start, len, real_len);
02512 return;
02513 }
02514
02515 if ((start + len) > real_len)
02516 {
02517 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
02518 start, len, real_len);
02519 len = real_len - start;
02520 }
02521
02522 d = _dbus_string_get_const_data_len (str, start, len);
02523
02524 _dbus_verbose_bytes (d, len);
02525 }
02526
02536 dbus_bool_t
02537 _dbus_marshal_basic_type (DBusString *str,
02538 char type,
02539 void *value,
02540 int byte_order)
02541 {
02542 dbus_bool_t retval;
02543
02544 switch (type)
02545 {
02546 case DBUS_TYPE_BYTE:
02547 case DBUS_TYPE_BOOLEAN:
02548 retval = _dbus_string_append_byte (str, *(unsigned char *)value);
02549 break;
02550 case DBUS_TYPE_INT32:
02551 case DBUS_TYPE_UINT32:
02552 return marshal_4_octets (str, byte_order, *(dbus_uint32_t *)value);
02553 break;
02554 #ifdef DBUS_HAVE_INT64
02555 case DBUS_TYPE_INT64:
02556 case DBUS_TYPE_UINT64:
02557 retval = _dbus_marshal_uint64 (str, byte_order, *(dbus_uint64_t *)value);
02558 break;
02559 #endif
02560 case DBUS_TYPE_DOUBLE:
02561 retval = _dbus_marshal_double (str, byte_order, *(double *)value);
02562 break;
02563 default:
02564 _dbus_assert_not_reached ("not a basic type");
02565 retval = FALSE;
02566 break;
02567 }
02568 return retval;
02569 }
02570
02581 dbus_bool_t
02582 _dbus_marshal_basic_type_array (DBusString *str,
02583 char element_type,
02584 const void *value,
02585 int len,
02586 int byte_order)
02587 {
02588 switch (element_type)
02589 {
02590 case DBUS_TYPE_BOOLEAN:
02591
02592
02593 case DBUS_TYPE_BYTE:
02594 return _dbus_marshal_byte_array (str, byte_order, value, len);
02595 break;
02596 case DBUS_TYPE_INT32:
02597 case DBUS_TYPE_UINT32:
02598 return marshal_4_octets_array (str, byte_order, value, len);
02599 break;
02600 #ifdef DBUS_HAVE_INT64
02601 case DBUS_TYPE_INT64:
02602 case DBUS_TYPE_UINT64:
02603 #endif
02604 case DBUS_TYPE_DOUBLE:
02605 return marshal_8_octets_array (str, byte_order, value, len);
02606 break;
02607 default:
02608 _dbus_assert_not_reached ("non basic type in array");
02609 break;
02610 }
02611 return FALSE;
02612 }
02613
02616 #ifdef DBUS_BUILD_TESTS
02617 #include "dbus-test.h"
02618 #include <stdio.h>
02619
02620 dbus_bool_t
02621 _dbus_marshal_test (void)
02622 {
02623 DBusString str;
02624 char *tmp1, *tmp2;
02625 int pos = 0, len;
02626 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
02627 #ifdef DBUS_HAVE_INT64
02628 dbus_int64_t array3[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
02629 DBUS_INT64_CONSTANT (0x456ffffffff),
02630 DBUS_INT64_CONSTANT (0x789ffffffff) }, *array4;
02631 #endif
02632 char *s;
02633 DBusString t;
02634
02635 if (!_dbus_string_init (&str))
02636 _dbus_assert_not_reached ("failed to init string");
02637
02638
02639 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
02640 _dbus_assert_not_reached ("could not marshal double value");
02641 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
02642 _dbus_assert_not_reached ("demarshal failed");
02643
02644 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
02645 _dbus_assert_not_reached ("could not marshal double value");
02646 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
02647 _dbus_assert_not_reached ("demarshal failed");
02648
02649
02650 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
02651 _dbus_assert_not_reached ("could not marshal signed integer value");
02652 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
02653 _dbus_assert_not_reached ("demarshal failed");
02654
02655 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
02656 _dbus_assert_not_reached ("could not marshal signed integer value");
02657 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
02658 _dbus_assert_not_reached ("demarshal failed");
02659
02660
02661 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
02662 _dbus_assert_not_reached ("could not marshal signed integer value");
02663 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
02664 _dbus_assert_not_reached ("demarshal failed");
02665
02666 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
02667 _dbus_assert_not_reached ("could not marshal signed integer value");
02668 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
02669 _dbus_assert_not_reached ("demarshal failed");
02670
02671 #ifdef DBUS_HAVE_INT64
02672
02673 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02674 _dbus_assert_not_reached ("could not marshal signed integer value");
02675 if (_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
02676 _dbus_assert_not_reached ("demarshal failed");
02677
02678 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02679 _dbus_assert_not_reached ("could not marshal signed integer value");
02680 if (_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) != DBUS_INT64_CONSTANT (-0x123456789abc7))
02681 _dbus_assert_not_reached ("demarshal failed");
02682
02683
02684 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02685 _dbus_assert_not_reached ("could not marshal signed integer value");
02686 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02687 _dbus_assert_not_reached ("demarshal failed");
02688
02689 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02690 _dbus_assert_not_reached ("could not marshal signed integer value");
02691 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02692 _dbus_assert_not_reached ("demarshal failed");
02693 #endif
02694
02695
02696 tmp1 = "This is the dbus test string";
02697 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
02698 _dbus_assert_not_reached ("could not marshal string");
02699 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
02700 if (!strcmp (tmp1, tmp2) == 0)
02701 _dbus_assert_not_reached ("demarshal failed");
02702 dbus_free (tmp2);
02703
02704 tmp1 = "This is the dbus test string";
02705 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
02706 _dbus_assert_not_reached ("could not marshal string");
02707 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
02708 if (!strcmp (tmp1, tmp2) == 0)
02709 _dbus_assert_not_reached ("demarshal failed");
02710 dbus_free (tmp2);
02711
02712
02713 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
02714 _dbus_assert_not_reached ("could not marshal integer array");
02715 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
02716 _dbus_assert_not_reached ("could not demarshal integer array");
02717
02718 if (len != 3)
02719 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02720 dbus_free (array2);
02721
02722 #ifdef DBUS_HAVE_INT64
02723
02724 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
02725 _dbus_assert_not_reached ("could not marshal integer array");
02726 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
02727 _dbus_assert_not_reached ("could not demarshal integer array");
02728
02729 if (len != 3)
02730 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02731 dbus_free (array4);
02732
02733
02734 _dbus_string_set_length (&str, 8);
02735
02736
02737 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
02738 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02739
02740 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02741 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02742 _dbus_string_get_const_data (&str)));
02743
02744
02745 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
02746 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02747
02748 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02749 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02750 _dbus_string_get_const_data (&str)));
02751
02752
02753 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02754 DBUS_LITTLE_ENDIAN,
02755 _dbus_string_get_data (&str));
02756
02757 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02758 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02759 _dbus_string_get_const_data (&str)));
02760
02761
02762 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02763 DBUS_BIG_ENDIAN,
02764 _dbus_string_get_data (&str));
02765
02766 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02767 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02768 _dbus_string_get_const_data (&str)));
02769
02770
02771 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
02772 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02773
02774 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02775 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02776 _dbus_string_get_const_data (&str)));
02777
02778
02779 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
02780 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02781
02782 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02783 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02784 _dbus_string_get_const_data (&str)));
02785
02786
02787 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02788 DBUS_LITTLE_ENDIAN,
02789 _dbus_string_get_data (&str));
02790
02791 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02792 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02793 _dbus_string_get_const_data (&str)));
02794
02795
02796 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02797 DBUS_BIG_ENDIAN,
02798 _dbus_string_get_data (&str));
02799
02800 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02801 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02802 _dbus_string_get_const_data (&str)));
02803
02804 #endif
02805
02806
02807 _dbus_string_set_length (&str, 4);
02808
02809
02810 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
02811 0, -0x123456);
02812
02813 _dbus_assert (-0x123456 ==
02814 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02815 _dbus_string_get_const_data (&str)));
02816
02817
02818 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
02819 0, -0x123456);
02820
02821 _dbus_assert (-0x123456 ==
02822 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02823 _dbus_string_get_const_data (&str)));
02824
02825
02826 _dbus_pack_int32 (-0x123456,
02827 DBUS_LITTLE_ENDIAN,
02828 _dbus_string_get_data (&str));
02829
02830 _dbus_assert (-0x123456 ==
02831 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02832 _dbus_string_get_const_data (&str)));
02833
02834
02835 _dbus_pack_int32 (-0x123456,
02836 DBUS_BIG_ENDIAN,
02837 _dbus_string_get_data (&str));
02838
02839 _dbus_assert (-0x123456 ==
02840 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02841 _dbus_string_get_const_data (&str)));
02842
02843
02844 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
02845 0, 0x123456);
02846
02847 _dbus_assert (0x123456 ==
02848 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02849 _dbus_string_get_const_data (&str)));
02850
02851
02852 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
02853 0, 0x123456);
02854
02855 _dbus_assert (0x123456 ==
02856 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02857 _dbus_string_get_const_data (&str)));
02858
02859
02860 _dbus_pack_uint32 (0x123456,
02861 DBUS_LITTLE_ENDIAN,
02862 _dbus_string_get_data (&str));
02863
02864 _dbus_assert (0x123456 ==
02865 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02866 _dbus_string_get_const_data (&str)));
02867
02868
02869 _dbus_pack_uint32 (0x123456,
02870 DBUS_BIG_ENDIAN,
02871 _dbus_string_get_data (&str));
02872
02873 _dbus_assert (0x123456 ==
02874 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02875 _dbus_string_get_const_data (&str)));
02876
02877
02878
02879
02880 _dbus_string_set_length (&str, 0);
02881
02882 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
02883 "Hello world");
02884
02885 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02886 _dbus_assert (strcmp (s, "Hello world") == 0);
02887 dbus_free (s);
02888
02889 _dbus_string_init_const (&t, "Hello world foo");
02890
02891 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02892 &t, _dbus_string_get_length (&t));
02893
02894 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02895 _dbus_assert (strcmp (s, "Hello world foo") == 0);
02896 dbus_free (s);
02897
02898 _dbus_string_init_const (&t, "Hello");
02899
02900 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02901 &t, _dbus_string_get_length (&t));
02902
02903 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02904 _dbus_assert (strcmp (s, "Hello") == 0);
02905 dbus_free (s);
02906
02907
02908
02909 _dbus_string_set_length (&str, 0);
02910
02911 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
02912 "Hello world");
02913
02914 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02915 _dbus_assert (strcmp (s, "Hello world") == 0);
02916 dbus_free (s);
02917
02918 _dbus_string_init_const (&t, "Hello world foo");
02919
02920 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02921 &t, _dbus_string_get_length (&t));
02922
02923 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02924 _dbus_assert (strcmp (s, "Hello world foo") == 0);
02925 dbus_free (s);
02926
02927 _dbus_string_init_const (&t, "Hello");
02928
02929 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02930 &t, _dbus_string_get_length (&t));
02931
02932 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02933 _dbus_assert (strcmp (s, "Hello") == 0);
02934 dbus_free (s);
02935
02936 _dbus_string_free (&str);
02937
02938 return TRUE;
02939 }
02940
02941 #endif