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
00619 dbus_bool_t
00620 _dbus_marshal_byte_array (DBusString *str,
00621 int byte_order,
00622 const unsigned char *value,
00623 int len)
00624 {
00625 int old_string_len;
00626
00627 old_string_len = _dbus_string_get_length (str);
00628
00629 if (!_dbus_marshal_uint32 (str, byte_order, len))
00630 {
00631
00632 _dbus_string_set_length (str, old_string_len);
00633
00634 return FALSE;
00635 }
00636
00637 if (len == 0)
00638 return TRUE;
00639 else
00640 return _dbus_string_append_len (str, value, len);
00641 }
00642
00643 static dbus_bool_t
00644 marshal_4_octets_array (DBusString *str,
00645 int byte_order,
00646 const dbus_uint32_t *value,
00647 int len)
00648 {
00649 int old_string_len;
00650 int array_start;
00651
00652 old_string_len = _dbus_string_get_length (str);
00653
00654 if (!_dbus_marshal_uint32 (str, byte_order, len * 4))
00655 goto error;
00656
00657 array_start = _dbus_string_get_length (str);
00658
00659 if (!_dbus_string_append_len (str, (const unsigned char*) value,
00660 len * 4))
00661 goto error;
00662
00663 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00664 {
00665 const unsigned char *d;
00666 const unsigned char *end;
00667
00668 d = _dbus_string_get_data (str) + array_start;
00669 end = d + len * 4;
00670 while (d != end)
00671 {
00672 *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
00673 d += 4;
00674 }
00675 }
00676
00677 return TRUE;
00678
00679 error:
00680
00681 _dbus_string_set_length (str, old_string_len);
00682
00683 return FALSE;
00684 }
00685
00686 static dbus_bool_t
00687 marshal_8_octets_array (DBusString *str,
00688 int byte_order,
00689 const DBusOctets8 *value,
00690 int len)
00691 {
00692 int old_string_len;
00693 int array_start;
00694
00695 old_string_len = _dbus_string_get_length (str);
00696
00697 if (!_dbus_marshal_uint32 (str, byte_order, len * 8))
00698 goto error;
00699
00700 array_start = _dbus_string_get_length (str);
00701
00702 if (!_dbus_string_append_len (str, (const unsigned char*) value,
00703 len * 8))
00704 goto error;
00705
00706 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
00707 {
00708 const unsigned char *d;
00709 const unsigned char *end;
00710
00711 d = _dbus_string_get_data (str) + array_start;
00712 end = d + len * 8;
00713 while (d != end)
00714 {
00715 #ifdef DBUS_HAVE_INT64
00716 *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
00717 #else
00718 swap_bytes ((unsigned char*) d, 8);
00719 #endif
00720 d += 8;
00721 }
00722 }
00723
00724 return TRUE;
00725
00726 error:
00727
00728 _dbus_string_set_length (str, old_string_len);
00729
00730 return FALSE;
00731 }
00732
00742 dbus_bool_t
00743 _dbus_marshal_int32_array (DBusString *str,
00744 int byte_order,
00745 const dbus_int32_t *value,
00746 int len)
00747 {
00748 return marshal_4_octets_array (str, byte_order,
00749 (const dbus_uint32_t*) value,
00750 len);
00751 }
00752
00762 dbus_bool_t
00763 _dbus_marshal_uint32_array (DBusString *str,
00764 int byte_order,
00765 const dbus_uint32_t *value,
00766 int len)
00767 {
00768 return marshal_4_octets_array (str, byte_order,
00769 value,
00770 len);
00771 }
00772
00773 #ifdef DBUS_HAVE_INT64
00774
00784 dbus_bool_t
00785 _dbus_marshal_int64_array (DBusString *str,
00786 int byte_order,
00787 const dbus_int64_t *value,
00788 int len)
00789 {
00790 return marshal_8_octets_array (str, byte_order,
00791 (const DBusOctets8*) value,
00792 len);
00793 }
00794
00804 dbus_bool_t
00805 _dbus_marshal_uint64_array (DBusString *str,
00806 int byte_order,
00807 const dbus_uint64_t *value,
00808 int len)
00809 {
00810 return marshal_8_octets_array (str, byte_order,
00811 (const DBusOctets8*) value,
00812 len);
00813 }
00814
00815 #endif
00816
00826 dbus_bool_t
00827 _dbus_marshal_double_array (DBusString *str,
00828 int byte_order,
00829 const double *value,
00830 int len)
00831 {
00832 return marshal_8_octets_array (str, byte_order,
00833 (const DBusOctets8*) value,
00834 len);
00835 }
00836
00846 dbus_bool_t
00847 _dbus_marshal_string_array (DBusString *str,
00848 int byte_order,
00849 const char **value,
00850 int len)
00851 {
00852 int i, old_string_len, array_start;
00853
00854 old_string_len = _dbus_string_get_length (str);
00855
00856
00857 if (!_dbus_marshal_uint32 (str, byte_order, 0))
00858 goto error;
00859
00860 array_start = _dbus_string_get_length (str);
00861
00862 for (i = 0; i < len; i++)
00863 if (!_dbus_marshal_string (str, byte_order, value[i]))
00864 goto error;
00865
00866
00867 _dbus_marshal_set_uint32 (str, byte_order,
00868 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00869 _dbus_string_get_length (str) - array_start);
00870
00871 return TRUE;
00872
00873 error:
00874
00875 _dbus_string_set_length (str, old_string_len);
00876
00877 return FALSE;
00878 }
00879
00889 dbus_bool_t
00890 _dbus_marshal_object_path (DBusString *str,
00891 int byte_order,
00892 const char **path,
00893 int path_len)
00894 {
00895 int array_start, old_string_len;
00896 int i;
00897
00898 old_string_len = _dbus_string_get_length (str);
00899
00900
00901 if (!_dbus_marshal_uint32 (str, byte_order, 0))
00902 goto nomem;
00903
00904 array_start = _dbus_string_get_length (str);
00905
00906 i = 0;
00907 while (i < path_len)
00908 {
00909 if (!_dbus_string_append_byte (str, '/'))
00910 goto nomem;
00911
00912 if (!_dbus_string_append (str, path[0]))
00913 goto nomem;
00914
00915 ++i;
00916 }
00917
00918
00919 _dbus_marshal_set_uint32 (str, byte_order,
00920 _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
00921 _dbus_string_get_length (str) - array_start);
00922
00923 return TRUE;
00924
00925 nomem:
00926
00927 _dbus_string_set_length (str, old_string_len);
00928
00929 return FALSE;
00930 }
00931
00932 static dbus_uint32_t
00933 demarshal_4_octets (const DBusString *str,
00934 int byte_order,
00935 int pos,
00936 int *new_pos)
00937 {
00938 const DBusRealString *real = (const DBusRealString*) str;
00939
00940 pos = _DBUS_ALIGN_VALUE (pos, 4);
00941
00942 if (new_pos)
00943 *new_pos = pos + 4;
00944
00945 return unpack_4_octets (byte_order, real->str + pos);
00946 }
00947
00948 static DBusOctets8
00949 demarshal_8_octets (const DBusString *str,
00950 int byte_order,
00951 int pos,
00952 int *new_pos)
00953 {
00954 const DBusRealString *real = (const DBusRealString*) str;
00955
00956 pos = _DBUS_ALIGN_VALUE (pos, 8);
00957
00958 if (new_pos)
00959 *new_pos = pos + 8;
00960
00961 return unpack_8_octets (byte_order, real->str + pos);
00962 }
00963
00973 double
00974 _dbus_demarshal_double (const DBusString *str,
00975 int byte_order,
00976 int pos,
00977 int *new_pos)
00978 {
00979 DBusOctets8 r;
00980
00981 r = demarshal_8_octets (str, byte_order, pos, new_pos);
00982
00983 return r.d;
00984 }
00985
00995 dbus_int32_t
00996 _dbus_demarshal_int32 (const DBusString *str,
00997 int byte_order,
00998 int pos,
00999 int *new_pos)
01000 {
01001 return (dbus_int32_t) demarshal_4_octets (str, byte_order, pos, new_pos);
01002 }
01003
01013 dbus_uint32_t
01014 _dbus_demarshal_uint32 (const DBusString *str,
01015 int byte_order,
01016 int pos,
01017 int *new_pos)
01018 {
01019 return demarshal_4_octets (str, byte_order, pos, new_pos);
01020 }
01021
01022 #ifdef DBUS_HAVE_INT64
01023
01033 dbus_int64_t
01034 _dbus_demarshal_int64 (const DBusString *str,
01035 int byte_order,
01036 int pos,
01037 int *new_pos)
01038 {
01039 DBusOctets8 r;
01040
01041 r = demarshal_8_octets (str, byte_order, pos, new_pos);
01042
01043 return r.s;
01044 }
01045
01055 dbus_uint64_t
01056 _dbus_demarshal_uint64 (const DBusString *str,
01057 int byte_order,
01058 int pos,
01059 int *new_pos)
01060 {
01061 DBusOctets8 r;
01062
01063 r = demarshal_8_octets (str, byte_order, pos, new_pos);
01064
01065 return r.u;
01066 }
01067
01068 #endif
01069
01086 char *
01087 _dbus_demarshal_string (const DBusString *str,
01088 int byte_order,
01089 int pos,
01090 int *new_pos)
01091 {
01092 int len;
01093 char *retval;
01094 const char *data;
01095
01096 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01097
01098 retval = dbus_malloc (len + 1);
01099
01100 if (!retval)
01101 return NULL;
01102
01103 data = _dbus_string_get_const_data_len (str, pos, len + 1);
01104
01105 if (!data)
01106 return NULL;
01107
01108 memcpy (retval, data, len + 1);
01109
01110 if (new_pos)
01111 *new_pos = pos + len + 1;
01112
01113 return retval;
01114 }
01115
01131 dbus_bool_t
01132 _dbus_demarshal_byte_array (const DBusString *str,
01133 int byte_order,
01134 int pos,
01135 int *new_pos,
01136 unsigned char **array,
01137 int *array_len)
01138 {
01139 int len;
01140 unsigned char *retval;
01141 const char *data;
01142
01143 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01144
01145 if (len == 0)
01146 {
01147 *array_len = len;
01148 *array = NULL;
01149
01150 if (new_pos)
01151 *new_pos = pos;
01152
01153 return TRUE;
01154 }
01155
01156 retval = dbus_malloc (len);
01157
01158 if (!retval)
01159 return FALSE;
01160
01161 data = _dbus_string_get_const_data_len (str, pos, len);
01162
01163 if (!data)
01164 {
01165 dbus_free (retval);
01166 return FALSE;
01167 }
01168
01169 memcpy (retval, data, len);
01170
01171 if (new_pos)
01172 *new_pos = pos + len;
01173
01174 *array = retval;
01175 *array_len = len;
01176
01177 return TRUE;
01178 }
01179
01180 static dbus_bool_t
01181 demarshal_4_octets_array (const DBusString *str,
01182 int byte_order,
01183 int pos,
01184 int *new_pos,
01185 dbus_uint32_t **array,
01186 int *array_len)
01187 {
01188 int len, i;
01189 dbus_uint32_t *retval;
01190 int byte_len;
01191
01192 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01193 len = byte_len / 4;
01194
01195 if (len == 0)
01196 {
01197 *array_len = 0;
01198 *array = NULL;
01199
01200 if (new_pos)
01201 *new_pos = pos;
01202
01203 return TRUE;
01204 }
01205
01206 if (!_dbus_string_copy_data_len (str, (char**) &retval,
01207 pos, byte_len))
01208 return FALSE;
01209
01210 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01211 {
01212 for (i = 0; i < len; i++)
01213 retval[i] = DBUS_UINT32_SWAP_LE_BE (retval[i]);
01214 }
01215
01216 if (new_pos)
01217 *new_pos = pos + byte_len;
01218
01219 *array_len = len;
01220 *array = retval;
01221
01222 return TRUE;
01223 }
01224
01225 static dbus_bool_t
01226 demarshal_8_octets_array (const DBusString *str,
01227 int byte_order,
01228 int pos,
01229 int *new_pos,
01230 DBusOctets8 **array,
01231 int *array_len)
01232 {
01233 int len, i;
01234 DBusOctets8 *retval;
01235 int byte_len;
01236
01237 byte_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01238 len = byte_len / 8;
01239
01240 if (len == 0)
01241 {
01242 *array_len = 0;
01243 *array = NULL;
01244
01245 if (new_pos)
01246 *new_pos = pos;
01247
01248 return TRUE;
01249 }
01250
01251 if (!_dbus_string_copy_data_len (str, (char**) &retval,
01252 pos, byte_len))
01253 return FALSE;
01254
01255 if (byte_order != DBUS_COMPILER_BYTE_ORDER)
01256 {
01257 for (i = 0; i < len; i++)
01258 {
01259 #ifdef DBUS_HAVE_INT64
01260 retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
01261 #else
01262 swap_bytes ((unsigned char *) &retval[i], 8);
01263 #endif
01264 }
01265 }
01266
01267 if (new_pos)
01268 *new_pos = pos + byte_len;
01269
01270 *array_len = len;
01271 *array = retval;
01272
01273 return TRUE;
01274 }
01275
01287 dbus_bool_t
01288 _dbus_demarshal_int32_array (const DBusString *str,
01289 int byte_order,
01290 int pos,
01291 int *new_pos,
01292 dbus_int32_t **array,
01293 int *array_len)
01294 {
01295 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01296 (dbus_uint32_t**) array, array_len);
01297 }
01298
01310 dbus_bool_t
01311 _dbus_demarshal_uint32_array (const DBusString *str,
01312 int byte_order,
01313 int pos,
01314 int *new_pos,
01315 dbus_uint32_t **array,
01316 int *array_len)
01317 {
01318 return demarshal_4_octets_array (str, byte_order, pos, new_pos,
01319 array, array_len);
01320 }
01321
01322 #ifdef DBUS_HAVE_INT64
01323
01335 dbus_bool_t
01336 _dbus_demarshal_int64_array (const DBusString *str,
01337 int byte_order,
01338 int pos,
01339 int *new_pos,
01340 dbus_int64_t **array,
01341 int *array_len)
01342 {
01343 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01344 (DBusOctets8**) array, array_len);
01345 }
01346
01358 dbus_bool_t
01359 _dbus_demarshal_uint64_array (const DBusString *str,
01360 int byte_order,
01361 int pos,
01362 int *new_pos,
01363 dbus_uint64_t **array,
01364 int *array_len)
01365 {
01366 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01367 (DBusOctets8**) array, array_len);
01368 }
01369
01370 #endif
01371
01383 dbus_bool_t
01384 _dbus_demarshal_double_array (const DBusString *str,
01385 int byte_order,
01386 int pos,
01387 int *new_pos,
01388 double **array,
01389 int *array_len)
01390 {
01391 return demarshal_8_octets_array (str, byte_order, pos, new_pos,
01392 (DBusOctets8**) array, array_len);
01393 }
01394
01406 dbus_bool_t
01407 _dbus_demarshal_string_array (const DBusString *str,
01408 int byte_order,
01409 int pos,
01410 int *new_pos,
01411 char ***array,
01412 int *array_len)
01413 {
01414 int bytes_len, i;
01415 int len, allocated;
01416 int end_pos;
01417 char **retval;
01418
01419 bytes_len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01420
01421 if (bytes_len == 0)
01422 {
01423 *array_len = 0;
01424 *array = NULL;
01425
01426 if (new_pos)
01427 *new_pos = pos;
01428
01429 return TRUE;
01430 }
01431
01432 len = 0;
01433 allocated = 4;
01434 end_pos = pos + bytes_len;
01435
01436 retval = dbus_new (char *, allocated);
01437
01438 if (!retval)
01439 return FALSE;
01440
01441 while (pos < end_pos)
01442 {
01443 retval[len] = _dbus_demarshal_string (str, byte_order, pos, &pos);
01444
01445 if (retval[len] == NULL)
01446 goto error;
01447
01448 len += 1;
01449
01450 if (len >= allocated - 1)
01451 {
01452 char **newp;
01453 newp = dbus_realloc (retval,
01454 sizeof (char*) * allocated * 2);
01455 if (newp == NULL)
01456 goto error;
01457
01458 allocated *= 2;
01459 retval = newp;
01460 }
01461 }
01462
01463 retval[len] = NULL;
01464
01465 if (new_pos)
01466 *new_pos = pos;
01467
01468 *array = retval;
01469 *array_len = len;
01470
01471 return TRUE;
01472
01473 error:
01474 for (i = 0; i < len; i++)
01475 dbus_free (retval[i]);
01476 dbus_free (retval);
01477
01478 return FALSE;
01479 }
01480
01482 #define VERBOSE_DECOMPOSE 0
01483
01495 dbus_bool_t
01496 _dbus_demarshal_object_path (const DBusString *str,
01497 int byte_order,
01498 int pos,
01499 int *new_pos,
01500 char ***path,
01501 int *path_len)
01502 {
01503 int len;
01504 char **retval;
01505 const char *data;
01506 int n_components;
01507 int i, j, comp;
01508
01509 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01510 data = _dbus_string_get_const_data_len (str, pos, len + 1);
01511 _dbus_assert (data != NULL);
01512
01513 #if VERBOSE_DECOMPOSE
01514 _dbus_verbose ("Decomposing path \"%s\"\n",
01515 data);
01516 #endif
01517
01518 n_components = 0;
01519 i = 0;
01520 while (i < len)
01521 {
01522 if (data[i] == '/')
01523 n_components += 1;
01524 ++i;
01525 }
01526
01527 retval = dbus_new0 (char*, n_components + 1);
01528
01529 if (retval == NULL)
01530 return FALSE;
01531
01532 comp = 0;
01533 i = 0;
01534 while (i < len)
01535 {
01536 if (data[i] == '/')
01537 ++i;
01538 j = i;
01539
01540 while (j < len && data[j] != '/')
01541 ++j;
01542
01543
01544 _dbus_assert (i < j);
01545 _dbus_assert (data[i] != '/');
01546 _dbus_assert (j == len || data[j] == '/');
01547
01548 #if VERBOSE_DECOMPOSE
01549 _dbus_verbose (" (component in [%d,%d))\n",
01550 i, j);
01551 #endif
01552
01553 retval[comp] = _dbus_memdup (&data[i], j - i + 1);
01554 if (retval[comp] == NULL)
01555 {
01556 dbus_free_string_array (retval);
01557 return FALSE;
01558 }
01559 retval[comp][j-i] = '\0';
01560 #if VERBOSE_DECOMPOSE
01561 _dbus_verbose (" (component %d = \"%s\")\n",
01562 comp, retval[comp]);
01563 #endif
01564
01565 ++comp;
01566 i = j;
01567 }
01568 _dbus_assert (i == len);
01569
01570 *path = retval;
01571 if (path_len)
01572 *path_len = n_components;
01573
01574 if (new_pos)
01575 *new_pos = pos + len + 1;
01576
01577 return TRUE;
01578 }
01579
01593 dbus_bool_t
01594 _dbus_marshal_get_arg_end_pos (const DBusString *str,
01595 int byte_order,
01596 int type,
01597 int pos,
01598 int *end_pos)
01599 {
01600 if (pos >= _dbus_string_get_length (str))
01601 return FALSE;
01602
01603 switch (type)
01604 {
01605 case DBUS_TYPE_INVALID:
01606 return FALSE;
01607 break;
01608
01609 case DBUS_TYPE_NIL:
01610 *end_pos = pos;
01611 break;
01612
01613 case DBUS_TYPE_BYTE:
01614 *end_pos = pos + 1;
01615 break;
01616
01617 case DBUS_TYPE_BOOLEAN:
01618 *end_pos = pos + 1;
01619 break;
01620
01621 case DBUS_TYPE_INT32:
01622 case DBUS_TYPE_UINT32:
01623 *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
01624 break;
01625
01626 case DBUS_TYPE_INT64:
01627 case DBUS_TYPE_UINT64:
01628 case DBUS_TYPE_DOUBLE:
01629
01630 *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
01631 break;
01632
01633 case DBUS_TYPE_OBJECT_PATH:
01634 case DBUS_TYPE_STRING:
01635 {
01636 int len;
01637
01638
01639 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01640
01641 *end_pos = pos + len + 1;
01642 }
01643 break;
01644
01645 case DBUS_TYPE_CUSTOM:
01646 {
01647 int len;
01648
01649
01650 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01651
01652 pos += len + 1;
01653
01654
01655 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01656
01657 *end_pos = pos + len;
01658 }
01659 break;
01660
01661 case DBUS_TYPE_ARRAY:
01662 {
01663 int len;
01664
01665
01666 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01667
01668 *end_pos = pos + len;
01669 }
01670 break;
01671
01672 case DBUS_TYPE_DICT:
01673 {
01674 int len;
01675
01676
01677 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
01678
01679 *end_pos = pos + len;
01680 }
01681 break;
01682
01683 default:
01684 _dbus_warn ("Unknown message arg type %d\n", type);
01685 _dbus_assert_not_reached ("Unknown message argument type\n");
01686 return FALSE;
01687 }
01688
01689 if (*end_pos > _dbus_string_get_length (str))
01690 return FALSE;
01691
01692 return TRUE;
01693 }
01694
01708 static int
01709 demarshal_and_validate_len (const DBusString *str,
01710 int byte_order,
01711 int pos,
01712 int *new_pos)
01713 {
01714 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
01715 unsigned int len;
01716
01717 _dbus_assert (new_pos != NULL);
01718
01719 if ((align_4 + 4) > _dbus_string_get_length (str))
01720 {
01721 _dbus_verbose ("not enough room in message for array length\n");
01722 return -1;
01723 }
01724
01725 if (!_dbus_string_validate_nul (str, pos,
01726 align_4 - pos))
01727 {
01728 _dbus_verbose ("array length alignment padding not initialized to nul\n");
01729 return -1;
01730 }
01731
01732 len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
01733
01734
01735
01736
01737
01738
01739
01740 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
01741 if (len > MAX_ARRAY_LENGTH)
01742 {
01743 _dbus_verbose ("array length %u exceeds maximum of %u\n",
01744 len, MAX_ARRAY_LENGTH);
01745 return -1;
01746 }
01747 else
01748 return (int) len;
01749 }
01750
01751 static dbus_bool_t
01752 validate_string (const DBusString *str,
01753 int pos,
01754 int len_without_nul,
01755 int *end_pos)
01756 {
01757 *end_pos = pos + len_without_nul + 1;
01758
01759 if (*end_pos > _dbus_string_get_length (str))
01760 {
01761 _dbus_verbose ("string length outside length of the message\n");
01762 return FALSE;
01763 }
01764
01765 if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
01766 {
01767 _dbus_verbose ("string arg not nul-terminated\n");
01768 return FALSE;
01769 }
01770
01771 if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
01772 {
01773 _dbus_verbose ("string is not valid UTF-8\n");
01774 return FALSE;
01775 }
01776
01777 return TRUE;
01778 }
01779
01791 dbus_bool_t
01792 _dbus_marshal_validate_type (const DBusString *str,
01793 int pos,
01794 int *type,
01795 int *end_pos)
01796 {
01797 const char *data;
01798
01799 if (pos >= _dbus_string_get_length (str))
01800 return FALSE;
01801
01802 data = _dbus_string_get_const_data_len (str, pos, 1);
01803
01804 if (_dbus_type_is_valid (*data))
01805 {
01806 *type = *data;
01807 if (end_pos != NULL)
01808 *end_pos = pos + 1;
01809 return TRUE;
01810 }
01811
01812 _dbus_verbose ("'%c' %d invalid type code\n", (int) *data, (int) *data);
01813
01814 return FALSE;
01815 }
01816
01817
01818
01819
01820 static dbus_bool_t
01821 validate_array_data (const DBusString *str,
01822 int byte_order,
01823 int depth,
01824 int type,
01825 int array_type_pos,
01826 int pos,
01827 int *new_pos,
01828 int end)
01829 {
01830 switch (type)
01831 {
01832 case DBUS_TYPE_INVALID:
01833 return FALSE;
01834 break;
01835
01836 case DBUS_TYPE_NIL:
01837 break;
01838
01839 case DBUS_TYPE_OBJECT_PATH:
01840 case DBUS_TYPE_STRING:
01841 case DBUS_TYPE_CUSTOM:
01842 case DBUS_TYPE_ARRAY:
01843 case DBUS_TYPE_DICT:
01844
01845
01846
01847
01848
01849
01850 while (pos < end)
01851 {
01852 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01853 type, array_type_pos, pos, &pos))
01854 return FALSE;
01855 }
01856 break;
01857
01858 case DBUS_TYPE_BYTE:
01859 pos = end;
01860 break;
01861
01862 case DBUS_TYPE_BOOLEAN:
01863 while (pos < end)
01864 {
01865 unsigned char c;
01866
01867 c = _dbus_string_get_byte (str, pos);
01868
01869 if (!(c == 0 || c == 1))
01870 {
01871 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
01872 return FALSE;
01873 }
01874
01875 ++pos;
01876 }
01877 break;
01878
01879 case DBUS_TYPE_INT32:
01880 case DBUS_TYPE_UINT32:
01881
01882
01883
01884 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01885 type, array_type_pos, pos, &pos))
01886 return FALSE;
01887 pos = _DBUS_ALIGN_VALUE (end, 4);
01888 break;
01889
01890 case DBUS_TYPE_INT64:
01891 case DBUS_TYPE_UINT64:
01892 case DBUS_TYPE_DOUBLE:
01893
01894
01895
01896 if (!_dbus_marshal_validate_arg (str, byte_order, depth,
01897 type, array_type_pos, pos, &pos))
01898 return FALSE;
01899 pos = _DBUS_ALIGN_VALUE (end, 8);
01900 break;
01901
01902 default:
01903 _dbus_verbose ("Unknown message arg type %d\n", type);
01904 return FALSE;
01905 }
01906
01907 *new_pos = pos;
01908
01909 return TRUE;
01910 }
01911
01932 dbus_bool_t
01933 _dbus_marshal_validate_arg (const DBusString *str,
01934 int byte_order,
01935 int depth,
01936 int type,
01937 int array_type_pos,
01938 int pos,
01939 int *end_pos)
01940 {
01941 if (pos > _dbus_string_get_length (str))
01942 {
01943 _dbus_verbose ("Validation went off the end of the message\n");
01944 return FALSE;
01945 }
01946
01947 #define MAX_VALIDATION_DEPTH 32
01948
01949 if (depth > MAX_VALIDATION_DEPTH)
01950 {
01951 _dbus_verbose ("Maximum recursion depth reached validating message\n");
01952 return FALSE;
01953 }
01954
01955 switch (type)
01956 {
01957 case DBUS_TYPE_INVALID:
01958 return FALSE;
01959 break;
01960
01961 case DBUS_TYPE_NIL:
01962 *end_pos = pos;
01963 break;
01964
01965 case DBUS_TYPE_BYTE:
01966 if (1 > _dbus_string_get_length (str) - pos)
01967 {
01968 _dbus_verbose ("no room for byte value\n");
01969 return FALSE;
01970 }
01971
01972 *end_pos = pos + 1;
01973 break;
01974
01975 case DBUS_TYPE_BOOLEAN:
01976 {
01977 unsigned char c;
01978
01979 if (1 > _dbus_string_get_length (str) - pos)
01980 {
01981 _dbus_verbose ("no room for boolean value\n");
01982 return FALSE;
01983 }
01984
01985 c = _dbus_string_get_byte (str, pos);
01986
01987 if (!(c == 0 || c == 1))
01988 {
01989 _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
01990 return FALSE;
01991 }
01992
01993 *end_pos = pos + 1;
01994 }
01995 break;
01996
01997 case DBUS_TYPE_INT32:
01998 case DBUS_TYPE_UINT32:
01999 {
02000 int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
02001
02002 if (!_dbus_string_validate_nul (str, pos,
02003 align_4 - pos))
02004 {
02005 _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
02006 return FALSE;
02007 }
02008
02009 *end_pos = align_4 + 4;
02010 }
02011 break;
02012
02013 case DBUS_TYPE_INT64:
02014 case DBUS_TYPE_UINT64:
02015 case DBUS_TYPE_DOUBLE:
02016 {
02017 int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
02018
02019 _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
02020
02021 if (!_dbus_string_validate_nul (str, pos,
02022 align_8 - pos))
02023 {
02024 _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
02025 return FALSE;
02026 }
02027
02028 *end_pos = align_8 + 8;
02029 }
02030 break;
02031
02032 case DBUS_TYPE_OBJECT_PATH:
02033 case DBUS_TYPE_STRING:
02034 {
02035 int len;
02036
02037
02038
02039
02040 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02041 if (len < 0)
02042 return FALSE;
02043
02044 if (!validate_string (str, pos, len, end_pos))
02045 return FALSE;
02046
02047 if (type == DBUS_TYPE_OBJECT_PATH)
02048 {
02049 if (!_dbus_string_validate_path (str, pos, len))
02050 return FALSE;
02051 }
02052 }
02053 break;
02054
02055 case DBUS_TYPE_CUSTOM:
02056 {
02057 int len;
02058
02059
02060
02061
02062 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02063 if (len < 0)
02064 return FALSE;
02065
02066 if (!validate_string (str, pos, len, &pos))
02067 return FALSE;
02068
02069
02070 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02071 if (len < 0)
02072 return FALSE;
02073
02074 *end_pos = pos + len;
02075 }
02076 break;
02077
02078 case DBUS_TYPE_ARRAY:
02079 {
02080 int len;
02081 int end;
02082 int array_type;
02083
02084 if (array_type_pos == -1)
02085 {
02086 array_type_pos = pos;
02087
02088 do
02089 {
02090 if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
02091 {
02092 _dbus_verbose ("invalid array type\n");
02093 return FALSE;
02094 }
02095
02096
02097
02098
02099
02100 if (array_type == DBUS_TYPE_NIL)
02101 {
02102 _dbus_verbose ("array of NIL is not allowed\n");
02103 return FALSE;
02104 }
02105 }
02106 while (array_type == DBUS_TYPE_ARRAY);
02107 }
02108 else
02109 array_type_pos++;
02110
02111 if (!_dbus_marshal_validate_type (str, array_type_pos, &array_type, NULL))
02112 {
02113 _dbus_verbose ("invalid array type\n");
02114 return FALSE;
02115 }
02116
02117 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02118 if (len < 0)
02119 return FALSE;
02120
02121 if (len > _dbus_string_get_length (str) - pos)
02122 {
02123 _dbus_verbose ("array length outside length of the message\n");
02124 return FALSE;
02125 }
02126
02127 end = pos + len;
02128
02129 if (!validate_array_data (str, byte_order, depth + 1,
02130 array_type, array_type_pos,
02131 pos, &pos, end))
02132 return FALSE;
02133
02134 if (pos < end)
02135 {
02136
02137
02138
02139 _dbus_verbose ("array length %d specified was longer than actual array contents by %d\n",
02140 len, end - pos);
02141 return FALSE;
02142 }
02143
02144 if (pos > end)
02145 {
02146 _dbus_verbose ("array contents exceeds array length %d by %d\n", len, pos - end);
02147 return FALSE;
02148 }
02149
02150 *end_pos = pos;
02151 }
02152 break;
02153
02154 case DBUS_TYPE_DICT:
02155 {
02156 int dict_type;
02157 int len;
02158 int end;
02159
02160 len = demarshal_and_validate_len (str, byte_order, pos, &pos);
02161 if (len < 0)
02162 return FALSE;
02163
02164 if (len > _dbus_string_get_length (str) - pos)
02165 {
02166 _dbus_verbose ("dict length outside length of the message\n");
02167 return FALSE;
02168 }
02169
02170 end = pos + len;
02171
02172 while (pos < end)
02173 {
02174
02175 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02176 DBUS_TYPE_STRING, -1, pos, &pos))
02177 return FALSE;
02178
02179 if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
02180 {
02181 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
02182 return FALSE;
02183 }
02184
02185
02186 if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
02187 dict_type, -1, pos, &pos))
02188 return FALSE;
02189 }
02190
02191 if (pos > end)
02192 {
02193 _dbus_verbose ("dict contents exceed stated dict length\n");
02194 return FALSE;
02195 }
02196
02197 *end_pos = pos;
02198 }
02199 break;
02200
02201 default:
02202 _dbus_verbose ("Unknown message arg type %d\n", type);
02203 return FALSE;
02204 }
02205
02206 if (*end_pos > _dbus_string_get_length (str))
02207 return FALSE;
02208
02209 return TRUE;
02210 }
02211
02217 dbus_bool_t
02218 _dbus_type_is_valid (int typecode)
02219 {
02220 switch (typecode)
02221 {
02222 case DBUS_TYPE_NIL:
02223 case DBUS_TYPE_BYTE:
02224 case DBUS_TYPE_BOOLEAN:
02225 case DBUS_TYPE_INT32:
02226 case DBUS_TYPE_UINT32:
02227 case DBUS_TYPE_INT64:
02228 case DBUS_TYPE_UINT64:
02229 case DBUS_TYPE_DOUBLE:
02230 case DBUS_TYPE_STRING:
02231 case DBUS_TYPE_CUSTOM:
02232 case DBUS_TYPE_ARRAY:
02233 case DBUS_TYPE_DICT:
02234 case DBUS_TYPE_OBJECT_PATH:
02235 return TRUE;
02236
02237 default:
02238 return FALSE;
02239 }
02240 }
02241
02250 void
02251 _dbus_verbose_bytes (const unsigned char *data,
02252 int len)
02253 {
02254 int i;
02255 const unsigned char *aligned;
02256
02257 _dbus_assert (len >= 0);
02258
02259
02260 aligned = _DBUS_ALIGN_ADDRESS (data, 4);
02261 if (aligned > data)
02262 aligned -= 4;
02263 _dbus_assert (aligned <= data);
02264
02265 if (aligned != data)
02266 {
02267 _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned);
02268 while (aligned != data)
02269 {
02270 _dbus_verbose (" ");
02271 ++aligned;
02272 }
02273 }
02274
02275
02276 i = 0;
02277 while (i < len)
02278 {
02279 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02280 {
02281 _dbus_verbose ("%4d\t%p: ",
02282 i, &data[i]);
02283 }
02284
02285 if (data[i] >= 32 &&
02286 data[i] <= 126)
02287 _dbus_verbose (" '%c' ", data[i]);
02288 else
02289 _dbus_verbose ("0x%s%x ",
02290 data[i] <= 0xf ? "0" : "", data[i]);
02291
02292 ++i;
02293
02294 if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
02295 {
02296 if (i > 3)
02297 _dbus_verbose ("BE: %d LE: %d",
02298 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
02299 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
02300
02301 if (i > 7 &&
02302 _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
02303 {
02304 _dbus_verbose (" dbl: %g",
02305 *(double*)&data[i-8]);
02306 }
02307
02308 _dbus_verbose ("\n");
02309 }
02310 }
02311
02312 _dbus_verbose ("\n");
02313 }
02314
02322 void
02323 _dbus_verbose_bytes_of_string (const DBusString *str,
02324 int start,
02325 int len)
02326 {
02327 const char *d;
02328 int real_len;
02329
02330 real_len = _dbus_string_get_length (str);
02331
02332 _dbus_assert (start >= 0);
02333
02334 if (start > real_len)
02335 {
02336 _dbus_verbose (" [%d,%d) is not inside string of length %d\n",
02337 start, len, real_len);
02338 return;
02339 }
02340
02341 if ((start + len) > real_len)
02342 {
02343 _dbus_verbose (" [%d,%d) extends outside string of length %d\n",
02344 start, len, real_len);
02345 len = real_len - start;
02346 }
02347
02348 d = _dbus_string_get_const_data_len (str, start, len);
02349
02350 _dbus_verbose_bytes (d, len);
02351 }
02352
02355 #ifdef DBUS_BUILD_TESTS
02356 #include "dbus-test.h"
02357 #include <stdio.h>
02358
02359 dbus_bool_t
02360 _dbus_marshal_test (void)
02361 {
02362 DBusString str;
02363 char *tmp1, *tmp2;
02364 int pos = 0, len;
02365 dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
02366 #ifdef DBUS_HAVE_INT64
02367 dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
02368 #endif
02369 char *s;
02370 DBusString t;
02371
02372 if (!_dbus_string_init (&str))
02373 _dbus_assert_not_reached ("failed to init string");
02374
02375
02376 if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
02377 _dbus_assert_not_reached ("could not marshal double value");
02378 if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
02379 _dbus_assert_not_reached ("demarshal failed");
02380
02381 if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
02382 _dbus_assert_not_reached ("could not marshal double value");
02383 if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
02384 _dbus_assert_not_reached ("demarshal failed");
02385
02386
02387 if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
02388 _dbus_assert_not_reached ("could not marshal signed integer value");
02389 if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
02390 _dbus_assert_not_reached ("demarshal failed");
02391
02392 if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
02393 _dbus_assert_not_reached ("could not marshal signed integer value");
02394 if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
02395 _dbus_assert_not_reached ("demarshal failed");
02396
02397
02398 if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
02399 _dbus_assert_not_reached ("could not marshal signed integer value");
02400 if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
02401 _dbus_assert_not_reached ("demarshal failed");
02402
02403 if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
02404 _dbus_assert_not_reached ("could not marshal signed integer value");
02405 if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
02406 _dbus_assert_not_reached ("demarshal failed");
02407
02408 #ifdef DBUS_HAVE_INT64
02409
02410 if (!_dbus_marshal_int64 (&str, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02411 _dbus_assert_not_reached ("could not marshal signed integer value");
02412 if (!_dbus_demarshal_int64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
02413 _dbus_assert_not_reached ("demarshal failed");
02414
02415 if (!_dbus_marshal_int64 (&str, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7)))
02416 _dbus_assert_not_reached ("could not marshal signed integer value");
02417 if (!_dbus_demarshal_int64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_INT64_CONSTANT (-0x123456789abc7))
02418 _dbus_assert_not_reached ("demarshal failed");
02419
02420
02421 if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02422 _dbus_assert_not_reached ("could not marshal signed integer value");
02423 if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02424 _dbus_assert_not_reached ("demarshal failed");
02425
02426 if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
02427 _dbus_assert_not_reached ("could not marshal signed integer value");
02428 if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
02429 _dbus_assert_not_reached ("demarshal failed");
02430 #endif
02431
02432
02433 tmp1 = "This is the dbus test string";
02434 if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
02435 _dbus_assert_not_reached ("could not marshal string");
02436 tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
02437 if (!strcmp (tmp1, tmp2) == 0)
02438 _dbus_assert_not_reached ("demarshal failed");
02439 dbus_free (tmp2);
02440
02441 tmp1 = "This is the dbus test string";
02442 if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
02443 _dbus_assert_not_reached ("could not marshal string");
02444 tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
02445 if (!strcmp (tmp1, tmp2) == 0)
02446 _dbus_assert_not_reached ("demarshal failed");
02447 dbus_free (tmp2);
02448
02449
02450 if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
02451 _dbus_assert_not_reached ("could not marshal integer array");
02452 if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
02453 _dbus_assert_not_reached ("could not demarshal integer array");
02454
02455 if (len != 3)
02456 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02457 dbus_free (array2);
02458
02459 #ifdef DBUS_HAVE_INT64
02460
02461 if (!_dbus_marshal_int64_array (&str, DBUS_BIG_ENDIAN, array3, 3))
02462 _dbus_assert_not_reached ("could not marshal integer array");
02463 if (!_dbus_demarshal_int64_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array4, &len))
02464 _dbus_assert_not_reached ("could not demarshal integer array");
02465
02466 if (len != 3)
02467 _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
02468 dbus_free (array4);
02469
02470
02471 _dbus_string_set_length (&str, 8);
02472
02473
02474 _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
02475 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02476
02477 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02478 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02479 _dbus_string_get_const_data (&str)));
02480
02481
02482 _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
02483 0, DBUS_INT64_CONSTANT (-0x123456789abc7));
02484
02485 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02486 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02487 _dbus_string_get_const_data (&str)));
02488
02489
02490 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02491 DBUS_LITTLE_ENDIAN,
02492 _dbus_string_get_data (&str));
02493
02494 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02495 _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
02496 _dbus_string_get_const_data (&str)));
02497
02498
02499 _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
02500 DBUS_BIG_ENDIAN,
02501 _dbus_string_get_data (&str));
02502
02503 _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
02504 _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
02505 _dbus_string_get_const_data (&str)));
02506
02507
02508 _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
02509 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02510
02511 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02512 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02513 _dbus_string_get_const_data (&str)));
02514
02515
02516 _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
02517 0, DBUS_UINT64_CONSTANT (0x123456789abc7));
02518
02519 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02520 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02521 _dbus_string_get_const_data (&str)));
02522
02523
02524 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02525 DBUS_LITTLE_ENDIAN,
02526 _dbus_string_get_data (&str));
02527
02528 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02529 _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
02530 _dbus_string_get_const_data (&str)));
02531
02532
02533 _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
02534 DBUS_BIG_ENDIAN,
02535 _dbus_string_get_data (&str));
02536
02537 _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
02538 _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
02539 _dbus_string_get_const_data (&str)));
02540
02541 #endif
02542
02543
02544 _dbus_string_set_length (&str, 4);
02545
02546
02547 _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
02548 0, -0x123456);
02549
02550 _dbus_assert (-0x123456 ==
02551 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02552 _dbus_string_get_const_data (&str)));
02553
02554
02555 _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
02556 0, -0x123456);
02557
02558 _dbus_assert (-0x123456 ==
02559 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02560 _dbus_string_get_const_data (&str)));
02561
02562
02563 _dbus_pack_int32 (-0x123456,
02564 DBUS_LITTLE_ENDIAN,
02565 _dbus_string_get_data (&str));
02566
02567 _dbus_assert (-0x123456 ==
02568 _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
02569 _dbus_string_get_const_data (&str)));
02570
02571
02572 _dbus_pack_int32 (-0x123456,
02573 DBUS_BIG_ENDIAN,
02574 _dbus_string_get_data (&str));
02575
02576 _dbus_assert (-0x123456 ==
02577 _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
02578 _dbus_string_get_const_data (&str)));
02579
02580
02581 _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
02582 0, 0x123456);
02583
02584 _dbus_assert (0x123456 ==
02585 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02586 _dbus_string_get_const_data (&str)));
02587
02588
02589 _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
02590 0, 0x123456);
02591
02592 _dbus_assert (0x123456 ==
02593 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02594 _dbus_string_get_const_data (&str)));
02595
02596
02597 _dbus_pack_uint32 (0x123456,
02598 DBUS_LITTLE_ENDIAN,
02599 _dbus_string_get_data (&str));
02600
02601 _dbus_assert (0x123456 ==
02602 _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
02603 _dbus_string_get_const_data (&str)));
02604
02605
02606 _dbus_pack_uint32 (0x123456,
02607 DBUS_BIG_ENDIAN,
02608 _dbus_string_get_data (&str));
02609
02610 _dbus_assert (0x123456 ==
02611 _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
02612 _dbus_string_get_const_data (&str)));
02613
02614
02615
02616
02617 _dbus_string_set_length (&str, 0);
02618
02619 _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
02620 "Hello world");
02621
02622 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02623 _dbus_assert (strcmp (s, "Hello world") == 0);
02624 dbus_free (s);
02625
02626 _dbus_string_init_const (&t, "Hello world foo");
02627
02628 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02629 &t, _dbus_string_get_length (&t));
02630
02631 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02632 _dbus_assert (strcmp (s, "Hello world foo") == 0);
02633 dbus_free (s);
02634
02635 _dbus_string_init_const (&t, "Hello");
02636
02637 _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
02638 &t, _dbus_string_get_length (&t));
02639
02640 s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
02641 _dbus_assert (strcmp (s, "Hello") == 0);
02642 dbus_free (s);
02643
02644
02645
02646 _dbus_string_set_length (&str, 0);
02647
02648 _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
02649 "Hello world");
02650
02651 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02652 _dbus_assert (strcmp (s, "Hello world") == 0);
02653 dbus_free (s);
02654
02655 _dbus_string_init_const (&t, "Hello world foo");
02656
02657 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02658 &t, _dbus_string_get_length (&t));
02659
02660 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02661 _dbus_assert (strcmp (s, "Hello world foo") == 0);
02662 dbus_free (s);
02663
02664 _dbus_string_init_const (&t, "Hello");
02665
02666 _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
02667 &t, _dbus_string_get_length (&t));
02668
02669 s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
02670 _dbus_assert (strcmp (s, "Hello") == 0);
02671 dbus_free (s);
02672
02673 _dbus_string_free (&str);
02674
02675 return TRUE;
02676 }
02677
02678 #endif