From c991bf83134ff32784429e1f55ed858834e28ec8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 25 Feb 2009 11:10:15 -0500 Subject: [PATCH] Bug 20137 - Fix alignment usage when demarshaling basics We can't safely type-pun from e.g. char * to DBusBasicValue *, because the latter has higher alignment requirements. Instead, create an explicit pointer for each case. Also, we mark each one volatile to sidestep strict aliasing issues, for the future when we turn on strict aliasing support. --- dbus/dbus-marshal-basic.c | 36 ++++++++++++++++++++++++------------ 1 files changed, 24 insertions(+), 12 deletions(-) diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 724d94b..e508d49 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -508,59 +508,70 @@ _dbus_marshal_read_basic (const DBusString *str, int *new_pos) { const char *str_data; - DBusBasicValue *vp; _dbus_assert (dbus_type_is_basic (type)); str_data = _dbus_string_get_const_data (str); - vp = value; switch (type) { case DBUS_TYPE_BYTE: - vp->byt = _dbus_string_get_byte (str, pos); + { + volatile char *vp = value; + *vp = _dbus_string_get_byte (str, pos); (pos)++; + } break; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: + { + volatile dbus_uint16_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 2); - vp->u16 = *(dbus_uint16_t *)(str_data + pos); + *vp = *(dbus_uint16_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u16 = DBUS_UINT16_SWAP_LE_BE (vp->u16); + *vp = DBUS_UINT16_SWAP_LE_BE (*vp); pos += 2; + } break; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_BOOLEAN: + { + volatile dbus_uint32_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 4); - vp->u32 = *(dbus_uint32_t *)(str_data + pos); + *vp = *(dbus_uint32_t *)(str_data + pos); if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u32 = DBUS_UINT32_SWAP_LE_BE (vp->u32); + *vp = DBUS_UINT32_SWAP_LE_BE (*vp); pos += 4; + } break; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: + { + volatile dbus_uint64_t *vp = value; pos = _DBUS_ALIGN_VALUE (pos, 8); #ifdef DBUS_HAVE_INT64 if (byte_order != DBUS_COMPILER_BYTE_ORDER) - vp->u64 = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); + *vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos)); else - vp->u64 = *(dbus_uint64_t*)(str_data + pos); + *vp = *(dbus_uint64_t*)(str_data + pos); #else - vp->u64 = *(DBus8ByteStruct*) (str_data + pos); + *vp = *(DBus8ByteStruct*) (str_data + pos); swap_8_octets (vp, byte_order); #endif pos += 8; + } break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: { int len; + volatile char **vp = value; len = _dbus_marshal_read_uint32 (str, pos, byte_order, &pos); - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } @@ -568,11 +579,12 @@ _dbus_marshal_read_basic (const DBusString *str, case DBUS_TYPE_SIGNATURE: { int len; + volatile char **vp = value; len = _dbus_string_get_byte (str, pos); pos += 1; - vp->str = (char*) str_data + pos; + *vp = (char*) str_data + pos; pos += len + 1; /* length plus nul */ } -- 1.6.0.6