Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

dbus-marshal.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */ 00002 /* dbus-marshal.c Marshalling routines 00003 * 00004 * Copyright (C) 2002 CodeFactory AB 00005 * Copyright (C) 2003, 2004 Red Hat, Inc. 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 /* from ORBit */ 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 /* !DBUS_HAVE_INT64 */ 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 /* DBUS_HAVE_INT64 */ 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 /* DBUS_HAVE_INT64 */ 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 /* DBUS_HAVE_INT64 */ 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 /* FIXME */ 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); /* pack into self, swapping as we go */ 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 /* DBUS_HAVE_INT64 */ 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 /* Restore the previous length */ 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 /* Restore the previous length */ 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 /* add a nul byte */ 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 /* Restore the previous length */ 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 /* Restore previous length */ 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 /* Restore previous length */ 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 /* DBUS_HAVE_INT64 */ 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 /* Set the length to 0 temporarily */ 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 /* Write the length now that we know it */ 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 /* Restore previous length */ 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 /* Set the length to 0 temporarily */ 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 /* Write the length now that we know it */ 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 /* Restore the previous length */ 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 /* DBUS_HAVE_INT64 */ 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 /* DBUS_HAVE_INT64 */ 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 /* DBUS_HAVE_INT64 */ 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 /* FIXME: do we want to post-normalize these ? */ 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 /* DBUS_HAVE_INT64 */ 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) /* -1 for NULL termination */ 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 /* Now [i, j) is the path component */ 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 /* Demarshal the length */ 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 /* Demarshal the string length */ 01815 len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos); 01816 01817 pos += len + 1; 01818 01819 /* Demarshal the data length */ 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 /* Demarshal the length */ 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 /* Demarshal the length */ 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 /* note that the len is the number of bytes, so we need it to be 01900 * at least SIZE_T_MAX, but make it smaller just to keep things 01901 * sane. We end up using ints for most sizes to avoid unsigned mess 01902 * so limit to maximum 32-bit signed int divided by at least 8, more 01903 * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes. 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 /* Faster validator for array data that doesn't call 01983 * validate_arg for each value 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 /* This clean recursion to validate_arg is what we 02010 * are doing logically for all types, but we don't 02011 * really want to call validate_arg for every byte 02012 * in a byte array, so the primitive types are 02013 * special-cased. 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 /* Call validate arg one time to check alignment padding 02047 * at start of array 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 /* Call validate arg one time to check alignment padding 02059 * at start of array 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 /* Demarshal the length, which does NOT include 02203 * nul termination 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 /* Demarshal the string length, which does NOT include 02225 * nul termination 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 /* Validate data */ 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 /* NIL values take up no space, so you couldn't iterate over an array of them. 02262 * array of nil seems useless anyway; the useful thing might be array of 02263 * (nil OR string) but we have no framework for that. 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 /* This should not be able to happen, as long as validate_arg moves forward; 02308 * but the check is here just to be paranoid. 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 /* Validate name */ 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 /* Validate element */ 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 /* Print blanks on first row if appropriate */ 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 /* now print the bytes */ 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 /* DBUS_HAVE_INT64 */ 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 /* FIXME: we canonicalize to 0 or 1 for the single boolean case 02592 * should we here too ? */ 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 /* DBUS_HAVE_INT64 */ 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 /* Marshal doubles */ 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 /* Marshal signed integers */ 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 /* Marshal unsigned integers */ 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 /* Marshal signed integers */ 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 /* Marshal unsigned integers */ 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 /* DBUS_HAVE_INT64 */ 02694 02695 /* Marshal strings */ 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 /* Marshal signed integer arrays */ 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 /* Marshal 64-bit signed integer arrays */ 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 /* set/pack 64-bit integers */ 02734 _dbus_string_set_length (&str, 8); 02735 02736 /* signed little */ 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 /* signed big */ 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 /* signed little pack */ 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 /* signed big pack */ 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 /* unsigned little */ 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 /* unsigned big */ 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 /* unsigned little pack */ 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 /* unsigned big pack */ 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 /* set/pack 32-bit integers */ 02807 _dbus_string_set_length (&str, 4); 02808 02809 /* signed little */ 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 /* signed big */ 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 /* signed little pack */ 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 /* signed big pack */ 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 /* unsigned little */ 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 /* unsigned big */ 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 /* unsigned little pack */ 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 /* unsigned big pack */ 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 /* Strings */ 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 /* Strings (big endian) */ 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 /* DBUS_BUILD_TESTS */

Generated on Mon Aug 16 17:40:09 2004 for D-BUS by doxygen 1.3.8