00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-marshal-byteswap.h"
00026 #include "dbus-marshal-basic.h"
00027 #include "dbus-signature.h"
00028
00034 static void
00035 byteswap_body_helper (DBusTypeReader *reader,
00036 dbus_bool_t walk_reader_to_end,
00037 int old_byte_order,
00038 int new_byte_order,
00039 unsigned char *p,
00040 unsigned char **new_p)
00041 {
00042 int current_type;
00043
00044 while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
00045 {
00046 switch (current_type)
00047 {
00048 case DBUS_TYPE_BYTE:
00049 ++p;
00050 break;
00051
00052 case DBUS_TYPE_INT16:
00053 case DBUS_TYPE_UINT16:
00054 {
00055 p = _DBUS_ALIGN_ADDRESS (p, 2);
00056 *((dbus_uint16_t*)p) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)p));
00057 p += 2;
00058 }
00059 break;
00060
00061 case DBUS_TYPE_BOOLEAN:
00062 case DBUS_TYPE_INT32:
00063 case DBUS_TYPE_UINT32:
00064 {
00065 p = _DBUS_ALIGN_ADDRESS (p, 4);
00066 *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
00067 p += 4;
00068 }
00069 break;
00070
00071 case DBUS_TYPE_INT64:
00072 case DBUS_TYPE_UINT64:
00073 case DBUS_TYPE_DOUBLE:
00074 {
00075 p = _DBUS_ALIGN_ADDRESS (p, 8);
00076 *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
00077 p += 8;
00078 }
00079 break;
00080
00081 case DBUS_TYPE_ARRAY:
00082 case DBUS_TYPE_STRING:
00083 case DBUS_TYPE_OBJECT_PATH:
00084 {
00085 dbus_uint32_t array_len;
00086
00087 p = _DBUS_ALIGN_ADDRESS (p, 4);
00088
00089 array_len = _dbus_unpack_uint32 (old_byte_order, p);
00090
00091 *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
00092 p += 4;
00093
00094 if (current_type == DBUS_TYPE_ARRAY)
00095 {
00096 int elem_type;
00097 int alignment;
00098
00099 elem_type = _dbus_type_reader_get_element_type (reader);
00100 alignment = _dbus_type_get_alignment (elem_type);
00101
00102 _dbus_assert ((array_len / alignment) < DBUS_MAXIMUM_ARRAY_LENGTH);
00103
00104 p = _DBUS_ALIGN_ADDRESS (p, alignment);
00105
00106 if (dbus_type_is_fixed (elem_type))
00107 {
00108 if (alignment > 1)
00109 _dbus_swap_array (p, array_len / alignment, alignment);
00110 p += array_len;
00111 }
00112 else
00113 {
00114 DBusTypeReader sub;
00115 const unsigned char *array_end;
00116
00117 array_end = p + array_len;
00118
00119 _dbus_type_reader_recurse (reader, &sub);
00120
00121 while (p < array_end)
00122 {
00123 byteswap_body_helper (&sub,
00124 FALSE,
00125 old_byte_order,
00126 new_byte_order,
00127 p, &p);
00128 }
00129 }
00130 }
00131 else
00132 {
00133 _dbus_assert (current_type == DBUS_TYPE_STRING ||
00134 current_type == DBUS_TYPE_OBJECT_PATH);
00135
00136 p += (array_len + 1);
00137 }
00138 }
00139 break;
00140
00141 case DBUS_TYPE_SIGNATURE:
00142 {
00143 dbus_uint32_t sig_len;
00144
00145 sig_len = *p;
00146
00147 p += (sig_len + 2);
00148 }
00149 break;
00150
00151 case DBUS_TYPE_VARIANT:
00152 {
00153
00154
00155
00156 dbus_uint32_t sig_len;
00157 DBusString sig;
00158 DBusTypeReader sub;
00159 int contained_alignment;
00160
00161 sig_len = *p;
00162 ++p;
00163
00164 _dbus_string_init_const_len (&sig, p, sig_len);
00165
00166 p += (sig_len + 1);
00167
00168 contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
00169
00170 p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00171
00172 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00173
00174 byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
00175 }
00176 break;
00177
00178 case DBUS_TYPE_STRUCT:
00179 case DBUS_TYPE_DICT_ENTRY:
00180 {
00181 DBusTypeReader sub;
00182
00183 p = _DBUS_ALIGN_ADDRESS (p, 8);
00184
00185 _dbus_type_reader_recurse (reader, &sub);
00186
00187 byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
00188 }
00189 break;
00190
00191 case DBUS_TYPE_UNIX_FD:
00192
00193 _dbus_assert_not_reached("attempted to byteswap unix fds which makes no sense");
00194 break;
00195
00196 default:
00197 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00198 break;
00199 }
00200
00201 if (walk_reader_to_end)
00202 _dbus_type_reader_next (reader);
00203 else
00204 break;
00205 }
00206
00207 if (new_p)
00208 *new_p = p;
00209 }
00210
00221 void
00222 _dbus_marshal_byteswap (const DBusString *signature,
00223 int signature_start,
00224 int old_byte_order,
00225 int new_byte_order,
00226 DBusString *value_str,
00227 int value_pos)
00228 {
00229 DBusTypeReader reader;
00230
00231 _dbus_assert (value_pos >= 0);
00232 _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
00233
00234 if (old_byte_order == new_byte_order)
00235 return;
00236
00237 _dbus_type_reader_init_types_only (&reader,
00238 signature, signature_start);
00239
00240 byteswap_body_helper (&reader, TRUE,
00241 old_byte_order, new_byte_order,
00242 _dbus_string_get_data_len (value_str, value_pos, 0),
00243 NULL);
00244 }
00245
00248