summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-01-27 23:39:26 +0000
committerHavoc Pennington <hp@redhat.com>2005-01-27 23:39:26 +0000
commitfddbc09c4a9125fcb168fb31ff300d4132919ea6 (patch)
treeb9f9779991f96ea4207a6795679a2f55087ac8ed
parent382d5ad0b4adf0070948fc2da623bc52894a7788 (diff)
2005-01-27 Havoc Pennington <hp@redhat.com>
* dbus/dbus-message.c: byteswap the message if you init an iterator to read/write from it * dbus/dbus-marshal-byteswap.c: new file implementing _dbus_marshal_byteswap() * dbus/dbus-marshal-basic.c: add _dbus_swap_array()
-rw-r--r--ChangeLog10
-rw-r--r--dbus/Makefile.am3
-rw-r--r--dbus/dbus-marshal-basic.c77
-rw-r--r--dbus/dbus-marshal-basic.h4
-rw-r--r--dbus/dbus-marshal-byteswap-util.c105
-rw-r--r--dbus/dbus-marshal-byteswap.c232
-rw-r--r--dbus/dbus-marshal-byteswap.h42
-rw-r--r--dbus/dbus-marshal-header.c22
-rw-r--r--dbus/dbus-marshal-header.h3
-rw-r--r--dbus/dbus-marshal-recursive-util.c99
-rw-r--r--dbus/dbus-marshal-recursive.h4
-rw-r--r--dbus/dbus-marshal-validate.c7
-rw-r--r--dbus/dbus-marshal-validate.h1
-rw-r--r--dbus/dbus-message.c80
-rw-r--r--dbus/dbus-test.c6
-rw-r--r--dbus/dbus-test.h1
16 files changed, 645 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 3a11130c..c1d24655 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2005-01-27 Havoc Pennington <hp@redhat.com>
+
+ * dbus/dbus-message.c: byteswap the message if you init an
+ iterator to read/write from it
+
+ * dbus/dbus-marshal-byteswap.c: new file implementing
+ _dbus_marshal_byteswap()
+
+ * dbus/dbus-marshal-basic.c: add _dbus_swap_array()
+
2005-01-26 Havoc Pennington <hp@redhat.com>
* dbus/dbus-marshal-validate-util.c: break this out (and fix
diff --git a/dbus/Makefile.am b/dbus/Makefile.am
index 36a6ec8d..2d08be6c 100644
--- a/dbus/Makefile.am
+++ b/dbus/Makefile.am
@@ -56,6 +56,8 @@ DBUS_LIB_SOURCES= \
dbus-keyring.h \
dbus-marshal-header.c \
dbus-marshal-header.h \
+ dbus-marshal-byteswap.c \
+ dbus-marshal-byteswap.h \
dbus-marshal-recursive.c \
dbus-marshal-recursive.h \
dbus-marshal-validate.c \
@@ -125,6 +127,7 @@ DBUS_UTIL_SOURCES= \
dbus-auth-util.c \
dbus-mainloop.c \
dbus-mainloop.h \
+ dbus-marshal-byteswap-util.c \
dbus-marshal-recursive-util.c \
dbus-marshal-validate-util.c \
dbus-message-factory.c \
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c
index 5cb43b88..cd5d4e45 100644
--- a/dbus/dbus-marshal-basic.c
+++ b/dbus/dbus-marshal-basic.c
@@ -820,6 +820,53 @@ marshal_1_octets_array (DBusString *str,
return TRUE;
}
+/**
+ * Swaps the elements of an array to the opposite byte order
+ *
+ * @param data start of array
+ * @param n_elements number of elements
+ * @param alignment size of each element
+ */
+void
+_dbus_swap_array (unsigned char *data,
+ int n_elements,
+ int alignment)
+{
+ unsigned char *d;
+ unsigned char *end;
+
+ _dbus_assert (_DBUS_ALIGN_ADDRESS (data, alignment) == data);
+
+ /* we use const_data and cast it off so DBusString can be a const string
+ * for the unit tests. don't ask.
+ */
+ d = data;
+ end = d + (n_elements * alignment);
+
+ if (alignment == 8)
+ {
+ while (d != end)
+ {
+#ifdef DBUS_HAVE_INT64
+ *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
+#else
+ swap_8_bytes ((DBusBasicValue*) d);
+#endif
+ d += 8;
+ }
+ }
+ else
+ {
+ _dbus_assert (alignment == 4);
+
+ while (d != end)
+ {
+ *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
+ d += 4;
+ }
+ }
+}
+
static void
swap_array (DBusString *str,
int array_start,
@@ -831,37 +878,11 @@ swap_array (DBusString *str,
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
{
- unsigned char *d;
- unsigned char *end;
-
/* we use const_data and cast it off so DBusString can be a const string
* for the unit tests. don't ask.
*/
- d = (unsigned char*) _dbus_string_get_const_data (str) + array_start;
- end = d + n_elements * alignment;
-
- if (alignment == 8)
- {
- while (d != end)
- {
-#ifdef DBUS_HAVE_INT64
- *((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
-#else
- swap_8_bytes ((DBusBasicValue*) d);
-#endif
- d += 8;
- }
- }
- else
- {
- _dbus_assert (alignment == 4);
-
- while (d != end)
- {
- *((dbus_uint32_t*)d) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)d));
- d += 4;
- }
- }
+ _dbus_swap_array ((unsigned char*) (_dbus_string_get_const_data (str) + array_start),
+ n_elements, alignment);
}
}
diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h
index d8ded1ca..375f2a3e 100644
--- a/dbus/dbus-marshal-basic.h
+++ b/dbus/dbus-marshal-basic.h
@@ -218,4 +218,8 @@ const char* _dbus_type_to_string (int typecode);
int _dbus_first_type_in_signature (const DBusString *str,
int pos);
+void _dbus_swap_array (unsigned char *data,
+ int n_elements,
+ int alignment);
+
#endif /* DBUS_MARSHAL_BASIC_H */
diff --git a/dbus/dbus-marshal-byteswap-util.c b/dbus/dbus-marshal-byteswap-util.c
new file mode 100644
index 00000000..eeea539c
--- /dev/null
+++ b/dbus/dbus-marshal-byteswap-util.c
@@ -0,0 +1,105 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap-util.c Would be in dbus-marshal-byteswap.c but tests/bus only
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#ifdef DBUS_BUILD_TESTS
+#include "dbus-marshal-byteswap.h"
+#include "dbus-test.h"
+#include <stdio.h>
+
+static void
+do_byteswap_test (int byte_order)
+{
+ int sequence;
+ DBusString signature;
+ DBusString body;
+ int opposite_order;
+
+ if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
+ _dbus_assert_not_reached ("oom");
+
+ opposite_order = byte_order == DBUS_LITTLE_ENDIAN ? DBUS_BIG_ENDIAN : DBUS_LITTLE_ENDIAN;
+
+ sequence = 0;
+ while (dbus_internal_do_not_use_generate_bodies (sequence,
+ byte_order,
+ &signature, &body))
+ {
+ DBusString copy;
+ DBusTypeReader body_reader;
+ DBusTypeReader copy_reader;
+
+ if (!_dbus_string_init (&copy))
+ _dbus_assert_not_reached ("oom");
+
+ if (!_dbus_string_copy (&body, 0, &copy, 0))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_marshal_byteswap (&signature, 0,
+ byte_order,
+ opposite_order,
+ &copy, 0);
+
+ _dbus_type_reader_init (&body_reader, byte_order, &signature, 0,
+ &body, 0);
+ _dbus_type_reader_init (&copy_reader, opposite_order, &signature, 0,
+ &copy, 0);
+
+ if (!_dbus_type_reader_equal_values (&body_reader, &copy_reader))
+ {
+ _dbus_verbose_bytes_of_string (&signature, 0,
+ _dbus_string_get_length (&signature));
+ _dbus_verbose_bytes_of_string (&body, 0,
+ _dbus_string_get_length (&body));
+ _dbus_verbose_bytes_of_string (&copy, 0,
+ _dbus_string_get_length (&copy));
+
+ _dbus_warn ("Byte-swapped data did not have same values as original data\n");
+ _dbus_assert_not_reached ("test failed");
+ }
+
+ _dbus_string_free (&copy);
+
+ _dbus_string_set_length (&signature, 0);
+ _dbus_string_set_length (&body, 0);
+ ++sequence;
+ }
+
+ _dbus_string_free (&signature);
+ _dbus_string_free (&body);
+
+ printf (" %d blocks swapped from order '%c' to '%c'\n",
+ sequence, byte_order, opposite_order);
+}
+
+dbus_bool_t
+_dbus_marshal_byteswap_test (void)
+{
+ do_byteswap_test (DBUS_LITTLE_ENDIAN);
+ do_byteswap_test (DBUS_BIG_ENDIAN);
+
+ return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */
diff --git a/dbus/dbus-marshal-byteswap.c b/dbus/dbus-marshal-byteswap.c
new file mode 100644
index 00000000..434d7e4b
--- /dev/null
+++ b/dbus/dbus-marshal-byteswap.c
@@ -0,0 +1,232 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap.c Swap a block of marshaled data
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "dbus-marshal-byteswap.h"
+#include "dbus-marshal-basic.h"
+
+/**
+ * @addtogroup DBusMarshal
+ * @{
+ */
+
+static void
+byteswap_body_helper (DBusTypeReader *reader,
+ dbus_bool_t walk_reader_to_end,
+ int old_byte_order,
+ int new_byte_order,
+ unsigned char *p,
+ unsigned char **new_p)
+{
+ int current_type;
+
+ while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
+ {
+ switch (current_type)
+ {
+ case DBUS_TYPE_BYTE:
+ ++p;
+ break;
+
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ {
+ p = _DBUS_ALIGN_ADDRESS (p, 4);
+ *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
+ p += 4;
+ }
+ break;
+
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ case DBUS_TYPE_DOUBLE:
+ {
+ p = _DBUS_ALIGN_ADDRESS (p, 8);
+#ifdef DBUS_HAVE_INT64
+ *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
+#else
+ _dbus_swap_array (p, 1, 8);
+#endif
+ p += 8;
+ }
+ break;
+
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ {
+ dbus_uint32_t array_len;
+
+ p = _DBUS_ALIGN_ADDRESS (p, 4);
+
+ array_len = _dbus_unpack_uint32 (old_byte_order, p);
+
+ *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
+ p += 4;
+
+ if (current_type == DBUS_TYPE_ARRAY)
+ {
+ int elem_type;
+ int alignment;
+
+ elem_type = _dbus_type_reader_get_element_type (reader);
+ alignment = _dbus_type_get_alignment (elem_type);
+
+ p = _DBUS_ALIGN_ADDRESS (p, alignment);
+
+ if (_dbus_type_is_fixed (elem_type))
+ {
+ if (alignment > 1)
+ _dbus_swap_array (p, array_len / alignment, alignment);
+ }
+ else
+ {
+ DBusTypeReader sub;
+ const unsigned char *array_end;
+
+ array_end = p + array_len;
+
+ _dbus_type_reader_recurse (reader, &sub);
+
+ while (p < array_end)
+ {
+ byteswap_body_helper (&sub,
+ FALSE,
+ old_byte_order,
+ new_byte_order,
+ p, &p);
+ }
+ }
+ }
+ else
+ {
+ _dbus_assert (current_type == DBUS_TYPE_STRING ||
+ current_type == DBUS_TYPE_OBJECT_PATH);
+
+ p += (array_len + 1); /* + 1 for nul */
+ }
+ }
+ break;
+
+ case DBUS_TYPE_SIGNATURE:
+ {
+ dbus_uint32_t sig_len;
+
+ sig_len = *p;
+
+ p += (sig_len + 2); /* +2 for len and nul */
+ }
+ break;
+
+ case DBUS_TYPE_VARIANT:
+ {
+ /* 1 byte sig len, sig typecodes, align to
+ * contained-type-boundary, values.
+ */
+ dbus_uint32_t sig_len;
+ DBusString sig;
+ DBusTypeReader sub;
+ int contained_alignment;
+
+ sig_len = *p;
+ ++p;
+
+ _dbus_string_init_const_len (&sig, p, sig_len);
+
+ p += (sig_len + 1); /* 1 for nul */
+
+ contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
+
+ p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
+
+ _dbus_type_reader_init_types_only (&sub, &sig, 0);
+
+ byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
+ }
+ break;
+
+ case DBUS_TYPE_STRUCT:
+ {
+ DBusTypeReader sub;
+
+ p = _DBUS_ALIGN_ADDRESS (p, 8);
+
+ _dbus_type_reader_recurse (reader, &sub);
+
+ byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
+ }
+ break;
+
+ default:
+ _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
+ break;
+ }
+
+ if (walk_reader_to_end)
+ _dbus_type_reader_next (reader);
+ else
+ break;
+ }
+
+ if (new_p)
+ *new_p = p;
+}
+
+/**
+ * Byteswaps the marshaled data in the given value_str.
+ *
+ * @param signature the types in the value_str
+ * @param signature_start where in signature is the signature
+ * @param old_byte_order the old byte order
+ * @param new_byte_order the new byte order
+ * @param value_str the string containing the body
+ * @param value_pos where the values start
+ */
+void
+_dbus_marshal_byteswap (const DBusString *signature,
+ int signature_start,
+ int old_byte_order,
+ int new_byte_order,
+ DBusString *value_str,
+ int value_pos)
+{
+ DBusTypeReader reader;
+
+ _dbus_assert (value_pos >= 0);
+ _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
+
+ if (old_byte_order == new_byte_order)
+ return;
+
+ _dbus_type_reader_init_types_only (&reader,
+ signature, signature_start);
+
+ byteswap_body_helper (&reader, TRUE,
+ old_byte_order, new_byte_order,
+ _dbus_string_get_data_len (value_str, value_pos, 0),
+ NULL);
+}
+
+/** @} */
+
+/* Tests in dbus-marshal-byteswap-util.c */
diff --git a/dbus/dbus-marshal-byteswap.h b/dbus/dbus-marshal-byteswap.h
new file mode 100644
index 00000000..e33cd74f
--- /dev/null
+++ b/dbus/dbus-marshal-byteswap.h
@@ -0,0 +1,42 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-byteswap.h Swap a block of marshaled data
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef DBUS_MARSHAL_BYTESWAP_H
+#define DBUS_MARSHAL_BYTESWAP_H
+
+#include <config.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-marshal-recursive.h>
+
+#ifndef PACKAGE
+#error "config.h not included here"
+#endif
+
+void _dbus_marshal_byteswap (const DBusString *signature,
+ int signature_start,
+ int old_byte_order,
+ int new_byte_order,
+ DBusString *value_str,
+ int value_pos);
+
+#endif /* DBUS_MARSHAL_BYTESWAP_H */
diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c
index 6102b6f0..b5a8d3d7 100644
--- a/dbus/dbus-marshal-header.c
+++ b/dbus/dbus-marshal-header.c
@@ -23,6 +23,7 @@
#include "dbus-marshal-header.h"
#include "dbus-marshal-recursive.h"
+#include "dbus-marshal-byteswap.h"
/**
* @addtogroup DBusMarshal
@@ -1448,6 +1449,27 @@ _dbus_header_get_flag (DBusHeader *header,
return (*flags_p & flag) != 0;
}
+/**
+ * Swaps the header into the given order if required.
+ *
+ * @param header the header
+ * @param new_order the new byte order
+ */
+void
+_dbus_header_byteswap (DBusHeader *header,
+ int new_order)
+{
+ if (header->byte_order == new_order)
+ return;
+
+ _dbus_marshal_byteswap (&_dbus_header_signature_str,
+ 0, header->byte_order,
+ new_order,
+ &header->data, 0);
+
+ header->byte_order = new_order;
+}
+
/** @} */
#ifdef DBUS_BUILD_TESTS
diff --git a/dbus/dbus-marshal-header.h b/dbus/dbus-marshal-header.h
index fed2888b..837c937b 100644
--- a/dbus/dbus-marshal-header.h
+++ b/dbus/dbus-marshal-header.h
@@ -125,7 +125,8 @@ dbus_bool_t _dbus_header_load (DBusHeader *header,
const DBusString *str,
int start,
int len);
-
+void _dbus_header_byteswap (DBusHeader *header,
+ int new_order);
diff --git a/dbus/dbus-marshal-recursive-util.c b/dbus/dbus-marshal-recursive-util.c
index 493672b6..08d030ab 100644
--- a/dbus/dbus-marshal-recursive-util.c
+++ b/dbus/dbus-marshal-recursive-util.c
@@ -21,11 +21,108 @@
*
*/
+#include <config.h>
+
+#ifdef DBUS_BUILD_TESTS
+
#include "dbus-marshal-recursive.h"
#include "dbus-marshal-basic.h"
#include "dbus-internals.h"
+#include <string.h>
-#ifdef DBUS_BUILD_TESTS
+static void
+basic_value_zero (DBusBasicValue *value)
+{
+
+#ifdef DBUS_HAVE_INT64
+ value->u64 = 0;
+#else
+ value->u64.first32 = 0;
+ value->u64.second32 = 0;
+#endif
+}
+
+static dbus_bool_t
+basic_value_equal (int type,
+ DBusBasicValue *lhs,
+ DBusBasicValue *rhs)
+{
+ if (type == DBUS_TYPE_STRING ||
+ type == DBUS_TYPE_SIGNATURE ||
+ type == DBUS_TYPE_OBJECT_PATH)
+ {
+ return strcmp (lhs->str, rhs->str) == 0;
+ }
+ else
+ {
+#ifdef DBUS_HAVE_INT64
+ return lhs->u64 == rhs->u64;
+#else
+ return lhs->u64.first32 == rhs->u64.first32 &&
+ lhs->u64.second32 == rhs->u64.second32;
+#endif
+ }
+}
+
+static dbus_bool_t
+equal_values_helper (DBusTypeReader *lhs,
+ DBusTypeReader *rhs)
+{
+ int lhs_type;
+ int rhs_type;
+
+ lhs_type = _dbus_type_reader_get_current_type (lhs);
+ rhs_type = _dbus_type_reader_get_current_type (rhs);
+
+ if (lhs_type != rhs_type)
+ return FALSE;
+
+ if (lhs_type == DBUS_TYPE_INVALID)
+ return TRUE;
+
+ if (_dbus_type_is_basic (lhs_type))
+ {
+ DBusBasicValue lhs_value;
+ DBusBasicValue rhs_value;
+
+ basic_value_zero (&lhs_value);
+ basic_value_zero (&rhs_value);
+
+ _dbus_type_reader_read_basic (lhs, &lhs_value);
+ _dbus_type_reader_read_basic (rhs, &rhs_value);
+
+ return basic_value_equal (lhs_type, &lhs_value, &rhs_value);
+ }
+ else
+ {
+ DBusTypeReader lhs_sub;
+ DBusTypeReader rhs_sub;
+
+ _dbus_type_reader_recurse (lhs, &lhs_sub);
+ _dbus_type_reader_recurse (rhs, &rhs_sub);
+
+ return equal_values_helper (&lhs_sub, &rhs_sub);
+ }
+}
+
+/**
+ * See whether the two readers point to identical data blocks.
+ *
+ * @param lhs reader 1
+ * @param rhs reader 2
+ * @returns #TRUE if the data blocks have the same values
+ */
+dbus_bool_t
+_dbus_type_reader_equal_values (const DBusTypeReader *lhs,
+ const DBusTypeReader *rhs)
+{
+ DBusTypeReader copy_lhs = *lhs;
+ DBusTypeReader copy_rhs = *rhs;
+
+ return equal_values_helper (&copy_lhs, &copy_rhs);
+}
+
+/* TESTS */
#include "dbus-test.h"
#include "dbus-list.h"
#include <stdio.h>
diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h
index 2e8317f4..45deeb5c 100644
--- a/dbus/dbus-marshal-recursive.h
+++ b/dbus/dbus-marshal-recursive.h
@@ -27,7 +27,6 @@
#include <config.h>
#include <dbus/dbus-protocol.h>
#include <dbus/dbus-list.h>
-#include <dbus/dbus-marshal-basic.h> /* this can vanish when we merge */
#ifndef PACKAGE
#error "config.h not included here"
@@ -168,6 +167,9 @@ dbus_bool_t _dbus_type_reader_delete (DBusTypeReader *
dbus_bool_t _dbus_type_reader_greater_than (const DBusTypeReader *lhs,
const DBusTypeReader *rhs);
+dbus_bool_t _dbus_type_reader_equal_values (const DBusTypeReader *lhs,
+ const DBusTypeReader *rhs);
+
void _dbus_type_writer_init (DBusTypeWriter *writer,
int byte_order,
DBusString *type_str,
diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
index e06add50..f15d2811 100644
--- a/dbus/dbus-marshal-validate.c
+++ b/dbus/dbus-marshal-validate.c
@@ -24,6 +24,8 @@
#include "dbus-internals.h"
#include "dbus-marshal-validate.h"
#include "dbus-marshal-recursive.h"
+#include "dbus-marshal-basic.h"
+#include "dbus-string.h"
/**
* @addtogroup DBusMarshal
@@ -254,6 +256,11 @@ validate_body_helper (DBusTypeReader *reader,
while (p < array_end)
{
+ /* FIXME we are calling a function per array element! very bad
+ * need if (dbus_type_is_fixed(elem_type)) here to just skip
+ * big blocks of ints/bytes/etc.
+ */
+
validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
if (validity != DBUS_VALID)
return validity;
diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h
index 195f46da..94b77989 100644
--- a/dbus/dbus-marshal-validate.h
+++ b/dbus/dbus-marshal-validate.h
@@ -25,7 +25,6 @@
#define DBUS_MARSHAL_VALIDATE_H
#include <config.h>
-#include <dbus/dbus-marshal-basic.h>
#ifndef PACKAGE
#error "config.h not included here"
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index cf15109b..38ae317a 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -25,6 +25,7 @@
#include "dbus-internals.h"
#include "dbus-marshal-recursive.h"
#include "dbus-marshal-validate.h"
+#include "dbus-marshal-byteswap.h"
#include "dbus-marshal-header.h"
#include "dbus-message-private.h"
#include "dbus-object-tree.h"
@@ -76,6 +77,57 @@ struct DBusMessageRealIter
} u; /**< the type writer or reader that does all the work */
};
+static void
+get_const_signature (DBusHeader *header,
+ const DBusString **type_str_p,
+ int *type_pos_p)
+{
+ if (_dbus_header_get_field_raw (header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ type_str_p,
+ type_pos_p))
+ {
+ *type_pos_p += 1; /* skip the signature length which is 1 byte */
+ }
+ else
+ {
+ *type_str_p = &_dbus_empty_signature_str;
+ *type_pos_p = 0;
+ }
+}
+
+/**
+ * Swaps the message to compiler byte order if required
+ *
+ * @param message the message
+ */
+static void
+_dbus_message_byteswap (DBusMessage *message)
+{
+ const DBusString *type_str;
+ int type_pos;
+
+ if (message->byte_order == DBUS_COMPILER_BYTE_ORDER)
+ return;
+
+ _dbus_verbose ("Swapping message into compiler byte order\n");
+
+ get_const_signature (&message->header, &type_str, &type_pos);
+
+ _dbus_marshal_byteswap (type_str, type_pos,
+ message->byte_order,
+ DBUS_COMPILER_BYTE_ORDER,
+ &message->body, 0);
+
+ message->byte_order = DBUS_COMPILER_BYTE_ORDER;
+
+ _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
+}
+
+#define ensure_byte_order(message) \
+ if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \
+ _dbus_message_byteswap (message)
+
/**
* Gets the data to be sent over the network for this message.
* The header and then the body should be written out.
@@ -250,25 +302,6 @@ set_or_delete_string_field (DBusMessage *message,
&value);
}
-static void
-get_const_signature (DBusHeader *header,
- const DBusString **type_str_p,
- int *type_pos_p)
-{
- if (_dbus_header_get_field_raw (header,
- DBUS_HEADER_FIELD_SIGNATURE,
- type_str_p,
- type_pos_p))
- {
- *type_pos_p += 1; /* skip the signature length which is 1 byte */
- }
- else
- {
- *type_str_p = &_dbus_empty_signature_str;
- *type_pos_p = 0;
- }
-}
-
#if 0
/* Probably we don't need to use this */
/**
@@ -1345,6 +1378,11 @@ _dbus_message_iter_init_common (DBusMessage *message,
{
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
+ /* Since the iterator will read or write who-knows-what from the
+ * message, we need to get in the right byte order
+ */
+ ensure_byte_order (message);
+
real->message = message;
real->changed_stamp = message->changed_stamp;
real->iter_type = iter_type;
@@ -1401,6 +1439,8 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
_dbus_warn ("dbus message changed byte order since iterator was created\n");
return FALSE;
}
+ /* because we swap the message into compiler order when you init an iter */
+ _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
}
else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
{
@@ -1409,6 +1449,8 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
_dbus_warn ("dbus message changed byte order since append iterator was created\n");
return FALSE;
}
+ /* because we swap the message into compiler order when you init an iter */
+ _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
}
else
{
diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c
index 5f51832c..eb2b8787 100644
--- a/dbus/dbus-test.c
+++ b/dbus/dbus-test.c
@@ -128,6 +128,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)
_dbus_warn ("recursive marshal tests disabled\n");
#endif
+ printf ("%s: running byteswap tests\n", "dbus-test");
+ if (!_dbus_marshal_byteswap_test ())
+ die ("byteswap marshaled data");
+
+ check_memleaks ();
+
printf ("%s: running memory tests\n", "dbus-test");
if (!_dbus_memory_test ())
die ("memory");
diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h
index 9a63914f..3a87afb1 100644
--- a/dbus/dbus-test.h
+++ b/dbus/dbus-test.h
@@ -33,6 +33,7 @@ dbus_bool_t _dbus_dict_test (void);
dbus_bool_t _dbus_list_test (void);
dbus_bool_t _dbus_marshal_test (void);
dbus_bool_t _dbus_marshal_recursive_test (void);
+dbus_bool_t _dbus_marshal_byteswap_test (void);
dbus_bool_t _dbus_marshal_header_test (void);
dbus_bool_t _dbus_marshal_validate_test (void);
dbus_bool_t _dbus_mem_pool_test (void);